当前位置: 首页 > 知识库问答 >
问题:

带有spring-boot和spring-security的JWT

云韬
2023-03-14

我对Spring保安很陌生。我试图在我的Spring-Boot应用程序中实现JWT来执行身份验证。我学习了示例代码,并且能够生成jwt。但是根据示例文件中的配置,我可以使用配置中的内存数据集来验证httpRequest中的输入。但是,我不理解如何将请求中发送的用户名密码与我的数据库中的值进行检查。请引导我。我的配置类是

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable().authorizeRequests()
            .antMatchers("/").permitAll()
            .antMatchers(HttpMethod.POST, "/login").permitAll()
            .anyRequest().authenticated()
            .and()
            // We filter the api/login requests
            .addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
                    UsernamePasswordAuthenticationFilter.class)
            // And filter other requests to check the presence of JWT in header
            .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");
}
}

在重写的configure(AuthenticationManagerBuilder auth)throws exception中,我可以设置将与/login路径的request中存在的凭据进行比较的凭据

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";

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) {
    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, Collections.emptyList()) :
                null;
    }
    return null;
}
}

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());
}
}

public class JWTAuthenticationFilter extends GenericFilterBean{

@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);
}
}

共有1个答案

韩安顺
2023-03-14

您需要实现UserDetailsService接口(访问您的数据库),并将其配置为Spring Security使用。

一个很好的例子(没有JWT,但这不是重点)可以在这里找到:Spring Security:Authentication with A Database-backed UserDetailsService

 类似资料:
  • 我得到了低于误差。有没有人可以帮助我如何在spring boot和spring Security中配置cors。在AngularJS中有没有任何事情我必须从UI端做。 加载http://localhost:8080/springgeolocation/login失败:请求的资源上没有“access-control-allow-origin”标头。因此,不允许访问源“http://localhost

  • 这是我的新SecurityConfig security-config.xml

  • 我尝试用OKTA为Spring应用程序设置SAML,我遵循http://developer.okta.com/code/java/spring_security_saml.html. 完成教程中的所有步骤后,我得到以下错误 SEVERE: Servlet.service() for servlet [jsp] in context with path [/spring-security-saml2

  • 现在我的是的一部分,位于正确的位置。平滑。 但是,由于是,它会被引导拾取并作为筛选器包含。所以我的过滤链看起来真的像: SSOAuthenticationFilter(由于是,因此包含) FilterChainProxy(spring自动配置) ... SecurityContextPersistenceFilter SSOAuthenticationFilter(包含在) ... 显然,我希望在

  • 我首先实现了Spring Security,并让它与持久令牌方法一起工作。然后我实现了Spring Social,经过长时间的努力,终于能够让它工作了。正在我的UserConnection表中创建适当的行。 我的问题是,当一个用户用Facebook登录到我的应用程序时,我的SignInAdapterImp会被调用。我在这里做用户认证。但是,我的UserDetailsServiceImp会立即被调用

  • 这是我启动应用程序时的控制台: 但是当我用邮递员访问时,我有一个错误: