Spring安全+ JWT +认证和hasRole无法正常工作?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring安全+ JWT +认证和hasRole无法正常工作?相关的知识,希望对你有一定的参考价值。

我的问题是我无法在用户登录时对其进行身份验证。我认为我的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;
}

} 请帮我!谢谢!

答案

首先,尝试在你的app运行的主应用程序类中创建BCryptPasswordEncoder的Bean,你的主要方法所在的类。只在BCryptPasswordEncoder类中初始化一个WebSecurityConfig对象。此外,如果您可以共享代码的git repo,那么解决起来会更容易。 Here是我的基本应用程序,它使用JWT和Spring Boot,非常熟悉你的代码。最有可能我们都试图从0Auth教程中学习。

以上是关于Spring安全+ JWT +认证和hasRole无法正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

Spring cloud微服务安全实战-6-2JWT认证之认证服务改造

Spring Cloud微服务安全实战_6-2_jwt认证之认证服务改造

Spring cloud微服务安全实战-6-5jwt改造之日志及错误处理

spring security jwt 安全校验

Spring 安全 SAML OpenAM

Spring Security+JWT简述