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

使用Springboot的JWT身份验证

柯清野
2023-03-14

我正在使用SpringBoot开发具有微服务架构的Rest Backend。为了保护endpoint,我使用了JWT令牌机制。我正在使用Zuul API网关

如果请求需要权限(来自JWT的角色),它将被转发到正确的微服务。Zuul api网关的“WebSecurityConfigrerAdapter”如下。

@Autowired
private JwtAuthenticationConfig config;

@Bean
public JwtAuthenticationConfig jwtConfig() {
    return new JwtAuthenticationConfig();
}

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
            .csrf().disable()
            .logout().disable()
            .formLogin().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .anonymous()
            .and()
                .exceptionHandling().authenticationEntryPoint(
                        (req, rsp, e) -> rsp.sendError(HttpServletResponse.SC_UNAUTHORIZED))
            .and()
                .addFilterAfter(new JwtTokenAuthenticationFilter(config),
                        UsernamePasswordAuthenticationFilter.class)
            .authorizeRequests()
                .antMatchers(config.getUrl()).permitAll()
                .antMatchers("/api/user/**").permitAll()
                .antMatchers("/api/package/**").hasRole("USER")
                .antMatchers("/api/dashboard/**").hasRole("USER")
                .antMatchers("/api/records/**").hasRole("USER");
}

这样,我必须在这个类中编写每个请求授权部分。因此,我希望使用方法级安全性,即“EnableGlobalMethodSecurity”。

问题是我应该如何将这个安全机制与其他微服务连接起来。因为当我将Spring Security依赖性添加到其他微服务时,它们表现为不同的Spring Security模块。我应该如何告诉其他使用zuul服务器安全性的微服务?

共有1个答案

鱼渝
2023-03-14

首先(如果我理解正确的话)安全实现在代理上?因为代理必须只做两件事:过滤和路由...

流程应该是这样的:https://www.rfc-editor.org/rfc/rfc6749#page-7

流程简介:

  1. 登录时,您应该传递用户凭据

在AccountServices中,您必须实现一个配置类来解码access\u令牌,并检查用户是否有权访问请求的资源

这里还有一个关于Spring中实现的OAuth2框架的好文档:http://projects.spring.io/spring-security-oauth/docs/oauth2.html

一些代码:

>

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

public final static String RESOURCE_ID = "server-resource";

@Value("${jwt.publicKey}")
private String publicKey;

@Value("${jwt.privateKey}")
private String privateKey;

@Autowired
private AuthenticationManager authenticationManager;

@Bean
public TokenStore tokenStore() {
    return new JwtTokenStore(accessTokenConverter());
}

@Bean
public JwtAccessTokenConverter accessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setVerifierKey(publicKey);
    converter.setSigningKey(privateKey);
    return converter;
}

@Bean
public TokenEnhancer customTokenEnhancer() {
    return new CustomTokenEnhancer();
}

@Override
public void configure(ClientDetailsServiceConfigurer client) throws Exception {
    client.inMemory()
        .withClient("client")
        .secret("clientsecret")
        .scopes("read", "write")
        .resourceIds("user")
        .authorizedGrantTypes("password", "refresh_token", "authorization_code")
        .authorities("ROLE_TRUSTED_CLIENT")
        .accessTokenValiditySeconds(tokenExpire) // one day available
        .refreshTokenValiditySeconds(refreshExpire);
}

@Override
public void configure(AuthorizationServerSecurityConfigurer server) throws Exception {
    server
        .tokenKeyAccess("hasAuthority('ROLE_TRUSTED_CLIENT')")
        .checkTokenAccess("hasAuthority('ROLE_TRUSTED_CLIENT')"); 
}

@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    endpoints
        .tokenStore(tokenStore())
        .authenticationManager(authenticationManager)
        .accessTokenConverter(accessTokenConverter());
}
}

关于公钥和私钥:私钥必须仅由AuthServer知道,并且必须在包括AuthService在内的任何服务中传递公钥。您可以在此处生成公钥和私钥:http://travistidwell.com/jsencrypt/demo/并在应用程序中添加这些键。yml文件,并使用值传递到configuration类。

在资源服务器上

@Configuration
@EnableResourceServer
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

@Value("${jwt.publicKey}")
private String publicKey;

@Bean
public TokenStore tokenStore() {
    return new JwtTokenStore(jwtAccessTokenConverter());
}

@Bean
protected JwtAccessTokenConverter jwtAccessTokenConverter() {
    JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
    converter.setVerifierKey(publicKey);
    return converter;
}

@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    resources
        .tokenStore(tokenStore())
        .resourceId("user");
}

@Override
public void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable()
        .authorizeRequests().antMatchers("/**").permitAll();
}

}

您必须做的唯一一件事是为资源服务(AccountService)创建一个配置类,以解码access\u令牌,并检查用户是否具有执行某些操作的角色。。。在这里,您必须以相同的方式仅传递公钥应用程序。yml文件。

关于EnableGlobalMethodSecurity(preprestenabled=true)注释您可以在控制器方法上添加预授权注释。

 类似资料:
  • 我正在开发一个具有自己的身份验证和授权机制的REST应用程序。我想使用JSON Web Tokens进行身份验证。以下是有效且安全的实现吗? < li >将开发一个REST API来接受用户名和密码并进行认证。要使用的HTTP方法是POST,因此没有缓存。此外,在传输时还会有安全SSL < li >在认证时,将创建两个JWTs访问令牌和刷新令牌。刷新令牌将具有更长的有效期。这两个令牌都将写入coo

  • jwt不应该仅仅用于认证用户吗?我读到过可以在里面存储非敏感的东西,比如用户ID。将权限级别之类的东西存储在令牌中可以吗?这样我可以避免数据库调用。

  • 我正在开发一个简单的API来处理Firebase所做的认证——稍后用于Android客户端。 因此,在Firebase控制台中,我启用了Facebook和Google登录方法并创建了一个示例html页面,我可以使用它来测试登录方法-下一个函数由按钮调用: 接下来,我使用令牌,并通过jQuery的一个简单ajax调用将它发送到我的API: 下一站:API后端。网芯。 在启动下,我配置了 JwtBea

  • 在身份验证等情况下,与会话相比,使用JWTs有什么优势? 它是作为独立方法使用还是在会话中使用?

  • 是否可以在ASP中支持多个JWT令牌发行者。净核心2?我想为外部服务提供一个API,我需要使用两个JWT代币来源——Firebase和定制JWT代币发行人。在ASP。NET core I可以为承载身份验证方案设置JWT身份验证,但只能为一个机构设置: 我可以有多个发行人和受众,但我不能设置多个权限。

  • 但请求呢?和是用户的属性,但应将它们发送到endpoint。如果我将资源发送到endpoint,则没有多大意义。 对此有没有办法,遵循JSONAPI并保持API的意义?