Spring security + JWT + 经过身份验证并且 hasRole 不起作用?
Posted
技术标签:
【中文标题】Spring security + JWT + 经过身份验证并且 hasRole 不起作用?【英文标题】:Spring security + JWT + authenticated and hasRole not working? 【发布时间】:2018-05-30 15:04:21 【问题描述】:我的问题是我无法在用户登录时对用户进行身份验证。 我觉得我的WebSecurityConfig文件有问题,如下:
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
// Web Security
@Autowired
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
// Authentication and Authorization
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable();
//h2 database console
http.headers().frameOptions().disable();
http.exceptionHandling()
.and().anonymous()
.and().servletApi()
.and().headers().cacheControl();
http.addFilterBefore(
new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(
new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
http.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/**").authenticated()
.antMatchers(HttpMethod.GET, "/login").permitAll();
http.logout()
.logoutUrl("/api/logout")
.logoutSuccessUrl("/api/index")
.invalidateHttpSession(true);
当我使用hasRole("CUSTOMER")
时,使用值message: Access is denied
进行响应。我不知道问题出在哪里。
几个相关文件:
JWTLoginFilter:
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter
public JWTLoginFilter(String url, AuthenticationManager authManager)
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException
User credentials = new User(request.getParameter("username"), request.getParameter("email"), request.getParameter("password"));
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
credentials.getEmail(),
credentials.getPassword(),
Collections.emptyList()
)
);
@Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException
TokenAuthenticationService.addAuthentication(response, authResult.getName());
JWTAuthenticationFilter:
public class JWTAuthenticationFilter extends GenericFilterBean
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException
Authentication authentication = TokenAuthenticationService.getAuthentication((HttpServletRequest) servletRequest);
SecurityContextHolder.getContext().setAuthentication(authentication);
filterChain.doFilter(servletRequest, servletResponse);
TokenAuthenticationService
public class TokenAuthenticationService
static final long EXPIRATIONTIME = 864_000_000; // 10 days
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);
public static Authentication getAuthentication(HttpServletRequest request)
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;
请帮我!谢谢!
【问题讨论】:
【参考方案1】:首先,尝试在您的应用程序运行的主应用程序类中创建BCryptPasswordEncoder
的Bean,您的主要方法所在的类。仅在WebSecurityConfig
类中初始化BCryptPasswordEncoder
对象。
此外,如果您可以共享代码的 git 存储库,则更容易解决。
Here 是我使用 JWT 和 Spring Boot 的非常基本的应用程序,对您的代码非常熟悉。很可能我们都试图从 0Auth 教程中学习。
【讨论】:
嗨,这是我的回购链接:github.com/homanhluc/…以上是关于Spring security + JWT + 经过身份验证并且 hasRole 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Security OAuth2 v5:NoSuchBeanDefinitionException:'org.springframework.security.oauth2.jwt.Jwt