4 java spring spring-security jwt
按照教程并Spring Security使用 JWT 设置如下:
WebSecurityConfig.java:
package ch.echoport.security;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests();
http.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/api/nextevent").permitAll()
.antMatchers("/api/login").permitAll()
.anyRequest().authenticated()
.and()
.addFilterBefore(new JWTLoginFilter("/api/authentication", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// Create a default account
auth.inMemoryAuthentication()
.withUser("admin")
.password("password")
.roles("ADMIN");
}
}
Run Code Online (Sandbox Code Playgroud)
JWTLoginFilter.java:
package ch.echoport.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {
public JWTLoginFilter(String url, AuthenticationManager authManager) {
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException, IOException, ServletException {
AccountCredentials creds = new ObjectMapper().readValue(req.getInputStream(), AccountCredentials.class);
return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(creds.getUsername(), creds.getPassword(), Collections.emptyList()));
}
@Override
protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) throws IOException, ServletException {
TokenAuthenticationService.addAuthentication(res, auth.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
JWTAuthenticationFilter.java:
package ch.echoport.security;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;
import org.springframework.security.core.Authentication;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class JWTAuthenticationFilter extends GenericFilterBean {
public JWTAuthenticationFilter() {
System.out.println("JWTAuthenticationFilter called");
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain filterChain)
throws IOException, ServletException {
Authentication authentication = TokenAuthenticationService
.getAuthentication((HttpServletRequest) request);
SecurityContextHolder.getContext()
.setAuthentication(authentication);
filterChain.doFilter(request, response);
}
}
Run Code Online (Sandbox Code Playgroud)
TokenAuthenticationService.java:
package ch.echoport.security;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security
.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import static java.util.Collections.emptyList;
@Service
public class TokenAuthenticationService {
static final long EXPIRATIONTIME = 14_400_000; // 4 hours (in milliseconds)
static final String SECRET = "ThisIsASecret";
static final String TOKEN_PREFIX = "Bearer";
static final String HEADER_STRING = "Authorization";
public static void addAuthentication(HttpServletResponse res, String username) {
String JWT = Jwts.builder()
.setSubject(username)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
}
static Authentication getAuthentication(HttpServletRequest request) {
System.out.println(request.toString());
String token = request.getHeader(HEADER_STRING);
if (token != null) {
// parse the token.
String user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
return user != null ?
new UsernamePasswordAuthenticationToken(user, null, emptyList()) :
null;
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
AccountCredentials.java:
package ch.echoport.security;
public class AccountCredentials {
private String username;
private String password;
public AccountCredentials() {}
public AccountCredentials(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Run Code Online (Sandbox Code Playgroud)
当使用类中设置的内存用户时,这一切都可以正常工作WebSecurityConfig。
现在,如果用户尝试登录,例如使用BCryptPasswordEncoder. 如果匹配,我该如何进行?我必须addAuthentication()在 中调用 - 方法吗TokenAuthenticationService?如果是这样,我必须传递什么作为第一个参数(HttpServletResponse)?如果没有,我必须采取什么步骤?
小智 5
您可以使用用户详细信息服务进行身份验证。创建您自己的服务实现 UserDetailsService 并从 Web 安全配置类中调用按用户名加载用户的方法。忽略内存中的身份验证,使用 auth.userDetailsService() 方法将您的服务作为此方法的参数。
您可以查找https://github.com/farukkkaradeniz/JwtAuthentication从数据库进行身份验证
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
Users user = userRepository.findOneByUserName(username);
if (user == null) {
throw new UsernameNotFoundException("User '" + username + "' not found");
}
return org.springframework.security.core.userdetails.User
.withUsername(username)
.password(user.getPassword())
.authorities(Collections.emptyList())
.accountExpired(false)
.accountLocked(false)
.credentialsExpired(false)
.disabled(false)
.build();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8742 次 |
| 最近记录: |