权限管理 springboot集成springSecurity Oauth2 JWT

这篇具有很好参考价值的文章主要介绍了权限管理 springboot集成springSecurity Oauth2 JWT。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、SpringSeurity的基础操作

1、引入主要依赖

2、加密器

3、实现自定义登录逻辑

4、访问限制

5、自定义异常处理 

6、通过注解的方式配置访问控制

二、Auth2认证方案

1、什么是Auth2认证

2、Oauth2最常用的授权模式 

3、依赖引入

4、添加配置类

5、测试

6、存在到Redis里,后续推荐使用JWT

三、JWT认证机制

1、JWT的组成

2、依赖引入

3、生成JWT的测试

4、解析JWT

5、自定义声明

四、SpringSecurityOauth2整合JWT

1、添加配置类

2、Jwt的解析

五、SpringSecurityOauth2实现单点登录

1、添加对应配置


一、SpringSeurity的基础操作

1、引入主要依赖

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

此时我们在启动项目时会发现对于的页面都需要登录才能访问!默认用户名、密码是user,密码是控制台启动时打印的密码。权限管理 springboot集成springSecurity Oauth2 JWT

权限管理 springboot集成springSecurity Oauth2 JWT

2、加密器

官方推荐使用BCryptPasswordEncoder这是一个基于Hash单向加密的加密类

    @Test
    public void contextLoads(){
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        //密码加密
        String encode = bCryptPasswordEncoder.encode("123");
        System.out.println(encode);
        System.out.println("==========================");
        //密码匹配,匹配成功返回true,否则返回false
        boolean matches = bCryptPasswordEncoder.matches("123", encode);
        System.out.println(matches);

    }

打印结果:

权限管理 springboot集成springSecurity Oauth2 JWT

 在项目使用时一般将其放到Spring容器中

@Configuration
public class SecurityConfig {

    @Bean
    public PasswordEncoder getPw(){
        return new BCryptPasswordEncoder();
    }
}

3、实现自定义登录逻辑

实现SpringSecurity里的UserDetailsService接口的LoadUserByUsername方法便可以实现自定义登录逻辑。以下代码将实现用户名为admin,密码为123的登录。一旦使用了自定义登录逻辑,原本的user和打印的password登录将不再生效。此时,通过admin 123便可登录。

对于登出SpringSecurity也提供了一个/logout的接口。

SpringSecurity框架以为我们提供了一个需要username和passsword参数的登录接口/login 的post请求,需要登录时框架调用的便是该接口。

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //查询数据库判断用户名是否操作,如果不存在就会抛出UsernameNotFoundException异常
        if (!"admin".equals(username)) {
            throw new UsernameNotFoundException("用户名不存在!");
        }
        //2、把查询出来的密码(注册时已经加密过)进行解析,或者直接把密码放入构造方法
        String password = passwordEncoder.encode("123");
        return new User(username, password, AuthorityUtils.commaSeparatedStringToAuthorityList("admin,normal,ROLE_abc"));
    }
}

4、访问限制

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder getPw() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //授权认证
        http.authorizeRequests()
                //error.html不需要被认证
                .antMatchers("/error.html").permitAll()
                //login.html不需要被认证
                .antMatchers("/login.html").permitAll()
                //指定角色访问
                .antMatchers("/main.html").hasRole("abc")
                //指定权限访问
                .antMatchers("/main.html").hasAuthority("admin")
                //多个权限都可访问
                .antMatchers("/main.html").hasAnyAuthority("admin,normal")
                //多个角色都可以访问
                .antMatchers("/main.html").hasAnyRole("ABC,abc")
                //通过指定ip地址进行访问,注意这里的ip与localhost转换的ip是不一样的,线上一般为服务器ip
                .antMatchers("/main.html").hasIpAddress("127.0.0.1")
                //所有请求都必须被认证,必须登录之后被访问
                .anyRequest().authenticated();

        //关闭csrf防护
        http.csrf().disable();
    }
}

在访问限制配置时,我们只需要集成WebSecurityConfigurerAdapter配置类configure(HttpSecurity http)方法即可。

权限管理 springboot集成springSecurity Oauth2 JWT

多个角色也类似:注意角色这里不要加前缀ROLE_

权限管理 springboot集成springSecurity Oauth2 JWT

 对应之前服务实现类的权限和角色:权限管理 springboot集成springSecurity Oauth2 JWT

5、自定义异常处理 

首先添加异常处理类实现AccessDeniedHandler接口的handle方法,handle方法里可自定义处理SpringSecurity的403等异常的处理。

@Component
public class MyAccessDeniedHandler implements AccessDeniedHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
        //设置响应状态码
        httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);
        httpServletResponse.setHeader("Content-Type", "application/json;charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write("{\"status\":\"error\",\"msg\":\"权限不足,请联系管理员\"}");
        writer.flush();
        writer.close();
    }
}

之后在SpringSecurity配置类里添加如下:

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //注入异常处理类
    @Autowired
    private MyAccessDeniedHandler myAccessDeniedHandler;

    ......

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ......

        //异常处理的配置
        http.exceptionHandling()
                .accessDeniedHandler(myAccessDeniedHandler);
    }
}

当权限不足报403时,这里会调用我们自定义的方法:

权限管理 springboot集成springSecurity Oauth2 JWT

6、通过注解的方式配置访问控制

 角色控制访问:注意这里的ROLE_前缀不能去

其他类开启注解@EnableGlobalMethodSecurity(securedEnabled = true)

权限管理 springboot集成springSecurity Oauth2 JWT

 控制类里添加@Secured(角色名)注解进行角色访问控制

权限管理 springboot集成springSecurity Oauth2 JWT

 当用户有ROLE_abC角色时会被允许访问,否则会报500错误!

使用@PreAuthorize注解来进行访问控制

类似的,启动类里的参数不同而已:

权限管理 springboot集成springSecurity Oauth2 JWT

进行角色访问控制:@PreAuthorize("hasRole('abc')")  //此时,有无ROLE_前缀都是可以被访问到的。要注意的时配置类里的hasRole方法是不允许以ROLE_前缀开头的这里有些差别。

同时也可用于权限控制访问:@PreAuthorize("hasAuthority('admin')")

二、Auth2认证方案

1、什么是Auth2认证

权限管理 springboot集成springSecurity Oauth2 JWT

权限管理 springboot集成springSecurity Oauth2 JWT

2、Oauth2最常用的授权模式 

权限管理 springboot集成springSecurity Oauth2 JWT

3、依赖引入

使用Oauth2时我们在SpringSecurity的依赖上添加如下依赖:

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>

4、添加配置类

(1)授权模式的配置类如下

SpringSecuirty的配置类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder getPw() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/oauth/**","/login/**","/logout/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
}

Oauth2的授权服务器配置:

@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client-id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置访问token的有效期
//                .accessTokenValiditySeconds(3600)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型
                .authorizedGrantTypes("authorization_code");

    }
}

Oauth2的资源服务器的配置类:

@Configuration
@EnableResourceServer  //开启资源服务器
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/user/**");
    }
}

密码模式的配置类如下:

SpringSecurity配置类:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder getPw() {
        return new BCryptPasswordEncoder();
    }

    //用于密码认证
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/oauth/**","/login/**","/logout/**").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().permitAll();
    }
}

授权服务器配置:

@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    //使用密码模式配置所需配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client-id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置访问token的有效期
//                .accessTokenValiditySeconds(3600)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型
                .authorizedGrantTypes("password");

    }
}

资源服务器配置:

与授权获取token时的一样

5、测试

启动服务器

授权模式获取接口资源的步骤

(1)获取授权码:

http://localhost:8080/oauth/authorize?response_type=code&client_id=admin&redirect_uri=http://www.baidu.com&scope=all

选择支持认证。 

权限管理 springboot集成springSecurity Oauth2 JWT

认证后记录下这个code里的值:

权限管理 springboot集成springSecurity Oauth2 JWT

(2)获取令牌

权限管理 springboot集成springSecurity Oauth2 JWT

用户名、密码就是授权服务器里的用户名密码 

权限管理 springboot集成springSecurity Oauth2 JWT

填写对应参数:

权限管理 springboot集成springSecurity Oauth2 JWT

 发生请求:

权限管理 springboot集成springSecurity Oauth2 JWT

(3)获取我们自己写的接口的数据:

权限管理 springboot集成springSecurity Oauth2 JWT

 选择Bearer auth认证填入对应token权限管理 springboot集成springSecurity Oauth2 JWT

获取到对应用户信息:

权限管理 springboot集成springSecurity Oauth2 JWT

 加密模式获取资源的步骤

(1)通过授权服务获取token

 认证配置与授权时一样权限管理 springboot集成springSecurity Oauth2 JWT

 传入参数有所不同:

权限管理 springboot集成springSecurity Oauth2 JWT

权限管理 springboot集成springSecurity Oauth2 JWT

通过用户名密码获取到对应token

权限管理 springboot集成springSecurity Oauth2 JWT (2)获取对应接口资源,与之前授权模式获取接口之源一样

6、存在到Redis里,后续推荐使用JWT

 以上授权的数据是放到内存中的实际开发过程中应将其放到redis里

(1)添加redis依赖与配置

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
spring:
  redis:
    database: 1
    host: my-server
    port: 6380
    password: 

(2)配置类

@Configuration
public class RedisConfig {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Bean
    public TokenStore redisTokenStore(){
        return new RedisTokenStore(redisConnectionFactory);
    }
}
@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    @Qualifier("redisTokenStore")
    private TokenStore tokenStore;

    //使用密码模式配置所需配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                .tokenStore(tokenStore);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client-id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置访问token的有效期
//                .accessTokenValiditySeconds(3600)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://www.baidu.com")
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型
                .authorizedGrantTypes("password");

    }
}

权限管理 springboot集成springSecurity Oauth2 JWT

放到获取token的接口后可以看到:数据已存在redis中去了

权限管理 springboot集成springSecurity Oauth2 JWT 

三、JWT认证机制

权限管理 springboot集成springSecurity Oauth2 JWT

1、JWT的组成

JWT是由.分割的如下三部分组成:

头部(Header)

Header 一般由两个部分组成:

  • alg
  • typ

alg是是所使用的hash算法,如:HMAC SHA256或RSA,typ是Token的类型,在这里就是:JWT。

{
  "alg": "HS256",
  "typ": "JWT"
}

然后使用Base64Url编码成第一部分:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.<second part>.<third part>

载荷(Payload)

这一部分是JWT主要的信息存储部分,其中包含了许多种的声明(claims)。

Claims的实体一般包含用户和一些元数据,这些claims分成三种类型:

  • reserved claims:预定义的 一些声明,并不是强制的但是推荐,它们包括 iss (issuer), exp (expiration time), sub (subject),aud(audience) 等(这里都使用三个字母的原因是保证 JWT 的紧凑)。
  • public claims: 公有声明,这个部分可以随便定义,但是要注意和 IANA JSON Web Token 冲突。
  • private claims: 私有声明,这个部分是共享被认定信息中自定义部分。

一个简单的Pyload可以是这样子的:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

这部分同样使用Base64Url编码成第二部分:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.<third part>

签名(Signature)

Signature是用来验证发送者的JWT的同时也能确保在期间不被篡改。

在创建该部分时候你应该已经有了编码后的Header和Payload,然后使用保存在服务端的秘钥对其签名,一个完整的JWT如下:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

因此使用JWT具有如下好处:

  • 通用:因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
  • 紧凑:JWT的构成非常简单,字节占用很小,可以通过 GET、POST 等放在 HTTP 的 header 中,非常便于传输。
  • 扩展:JWT是自我包涵的,包含了必要的所有信息,不需要在服务端保存会话信息, 非常易于应用的扩展。

权限管理 springboot集成springSecurity Oauth2 JWT

2、依赖引入

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

3、生成JWT的测试

    private void createToken() {
        //当前系统时间
        long now = System.currentTimeMillis();
        //过期时间,1分钟
        long exp = now + 60 * 1000;

        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                //声明的标识{“jti”:"8888"}
                .setId("8888")
                //主体,用户{“sub”:"Rose"}
                .setSubject("Rose")
                //创建日期{“ita”:“xxxxxx”}
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, "xxxxxx")
                //设置过期时间
                .setExpiration(new Date(exp));
        //获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);

        System.out.println("=======================================");
        String[] split = token.split("\\.");
        System.out.println(Base64Codec.BASE64.decodeToString(split[0]));
        System.out.println(Base64Codec.BASE64.decodeToString(split[1]));
        //无法解密
        System.out.println(Base64Codec.BASE64.decodeToString(split[2]));
    }

打印如下:密码盐一般为服务器的私钥

权限管理 springboot集成springSecurity Oauth2 JWT

4、解析JWT

    private void parseJWT() {
        String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY2NTAzNzc0MSwiZXhwIjoxNjY1MDM3ODAxfQ.jGZrGW0sYyfuatsi1xtYXI8pPflRZR4DY3BbwmSKN0M";
        //解析token获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("xxxxxx")
                .parseClaimsJws(jwt)
                .getBody();
        System.out.println("id:" + claims.getId());
        System.out.println("subject:" + claims.getSubject());
        System.out.println("issuedAt:" + claims.getIssuedAt());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("签发时间:" + simpleDateFormat.format(claims.getIssuedAt()));
        System.out.println("过期时间:" + simpleDateFormat.format(claims.getExpiration()));
        System.out.println("当前时间:" + simpleDateFormat.format(new Date()));
    }

 权限管理 springboot集成springSecurity Oauth2 JWT

5、自定义声明

    //自定义声明
    private void createJWTByClaims() {
        //当前系统时间
        long now = System.currentTimeMillis();
        //过期时间,1分钟
        long exp = now + 60 * 1000;

        //创建JwtBuilder对象
        JwtBuilder jwtBuilder = Jwts.builder()
                //声明的标识{“jti”:"8888"}
                .setId("8888")
                //主体,用户{“sub”:"Rose"}
                .setSubject("Rose")
                //创建日期{“ita”:“xxxxxx”}
                .setIssuedAt(new Date())
                .signWith(SignatureAlgorithm.HS256, "xxxxxx")
                //设置过期时间
                .setExpiration(new Date(exp))
                //自定义声明的使用
                .claim("roles", "admin")
                .claim("logo", "xxx.jpg");
        //直接传入Map
//                .setClaims(map)
        //获取jwt的token
        String token = jwtBuilder.compact();
        System.out.println(token);
    }

解析:

private void parseJWTClaims() {
        String jwt = "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ODg4Iiwic3ViIjoiUm9zZSIsImlhdCI6MTY2NTAzODQwMiwiZXhwIjoxNjY1MDM4NDYxLCJyb2xlcyI6ImFkbWluIiwibG9nbyI6Inh4eC5qcGcifQ.fzyWQ_HG725kDoZ0zljHkIiIrO1mhl_u77r81ZeT1FA";
        //解析token获取负载中声明的对象
        Claims claims = Jwts.parser()
                .setSigningKey("xxxxxx")
                .parseClaimsJws(jwt)
                .getBody();
        System.out.println("id:" + claims.getId());
        System.out.println("subject:" + claims.getSubject());
        System.out.println("issuedAt:" + claims.getIssuedAt());
        System.out.println("roles:" + claims.get("roles"));
        System.out.println("logo:" + claims.get("logo"));
    }

权限管理 springboot集成springSecurity Oauth2 JWT

四、SpringSecurityOauth2整合JWT

1、添加配置类

Jwt的配置类

@Configuration
public class JwtTokenStoreConfig {

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

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
        //配置jwt使用的密钥
        accessTokenConverter.setSigningKey("test_key");
        return accessTokenConverter;
    }

    @Bean
    public JwtTokenEnhancer jwtTokenEnhancer(){
        return new JwtTokenEnhancer();
    }
}

Jwt内容增强器的配置类:

public class JwtTokenEnhancer implements TokenEnhancer {


    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken oAuth2AccessToken, OAuth2Authentication oAuth2Authentication) {
        Map<String, Object> info = new HashMap<>();
        //放入jwt里的内容
        info.put("enhance", "enhance info");
        ((DefaultOAuth2AccessToken) oAuth2AccessToken).setAdditionalInformation(info);
        return oAuth2AccessToken;
    }
}

授权服务器配置类:

@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    @Qualifier("jwtTokenStore")
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private JwtTokenEnhancer jwtTokenEnhancer;

    //使用密码模式配置所需配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //配置JWT内容增强器
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> delegates = new ArrayList<>();
        delegates.add(jwtTokenEnhancer);
        delegates.add(jwtAccessTokenConverter);
        enhancerChain.setTokenEnhancers(delegates);

        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                //配置存储令牌策略
                .tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter)
                //配置内容增强器
                .tokenEnhancer(enhancerChain);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client-id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置访问token的有效期
                .accessTokenValiditySeconds(3600)
                //配置刷新令牌的有效期
                .refreshTokenValiditySeconds(864000)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://localhost:8081/login")
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型, 刷新令牌
                .authorizedGrantTypes("password","refresh_token");
    }
}

权限管理 springboot集成springSecurity Oauth2 JWT

重启项目:

使用正确密码模式的访问接口进行测试:可以看到目前的token已经是JWT的token了

权限管理 springboot集成springSecurity Oauth2 JWT

 将此token放到官网解析可以看到对应增加的信息:

权限管理 springboot集成springSecurity Oauth2 JWT

2、Jwt的解析

这里需要引入之前集成JWT的依赖

添加访问接口进行测试

    @GetMapping("/getCurrentUser")
    public Object getCurrentUser(Authentication authentication, HttpServletRequest request) {
        String head = request.getHeader("Authorization");
        String token = head.substring(head.indexOf("bearer") + 7);
        return Jwts.parser()
                .setSigningKey("test_key".getBytes(StandardCharsets.UTF_8))
                .parseClaimsJws(token)
                .getBody();
    }

访问该接口,仅需传入请求头Authorization和对应的bearer+JWT即可:

权限管理 springboot集成springSecurity Oauth2 JWT

 解析完毕:

权限管理 springboot集成springSecurity Oauth2 JWT

3、刷新token

授权服务器配置如下:

权限管理 springboot集成springSecurity Oauth2 JWT

 再次测试:可以看到刷新时的token

权限管理 springboot集成springSecurity Oauth2 JWT

权限管理 springboot集成springSecurity Oauth2 JWT

五、SpringSecurityOauth2实现单点登录

我以之前的授权服务器作为授权服务器,现在在创建一个服务器作为单点请求登录的服务器客户端。依赖与授权服务器相同。

1、添加对应配置

server:
  port: 8081
  servlet:
    session:
      # 防止Cookie冲突,冲突会导致登录验证不通过
      cookie:
        name: OAUTH2-CLIENT-SESSIONID01
# 授权服务器地址
oauth2-server-url: http://localhost:8080
# 与授权服务器对应的配置
security:
  oauth2:
    client:
      client-id: admin
      client-secret: 112233
      user-authorization-uri: ${oauth2-server-url}/oauth/authorize
      access-token-uri: ${oauth2-server-url}/oauth/token
    resource:
      jwt:
        key-uri: ${oauth2-server-url}/oauth/token_key

权限管理 springboot集成springSecurity Oauth2 JWT

使用单点登录时授权服务器的授权配置类: 

@Configuration
@EnableAuthorizationServer  //开启授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    @Qualifier("jwtTokenStore")
    private TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private JwtTokenEnhancer jwtTokenEnhancer;

    //使用密码模式配置所需配置
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        //配置JWT内容增强器
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> delegates = new ArrayList<>();
        delegates.add(jwtTokenEnhancer);
        delegates.add(jwtAccessTokenConverter);
        enhancerChain.setTokenEnhancers(delegates);

        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
                //配置存储令牌策略
                .tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter)
                //配置内容增强器
                .tokenEnhancer(enhancerChain);
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                //配置client-id
                .withClient("admin")
                //配置client-secret
                .secret(passwordEncoder.encode("112233"))
                //配置访问token的有效期
                .accessTokenValiditySeconds(3600)
                //配置刷新令牌的有效期
                .refreshTokenValiditySeconds(864000)
                //配置redirect_uri,用于授权成功后跳转
                .redirectUris("http://localhost:8081/login")
                //自动授权配置
                .autoApprove(true)
                //配置申请的权限范围
                .scopes("all")
                //配置grant_type,表示授权类型, 刷新令牌
                .authorizedGrantTypes("password", "refresh_token", "authorization_code");
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        //获取密钥需要身份认证,使用单点登录时必须配置
        security.tokenKeyAccess("isAuthenticated()");
    }
}

 访问客户端的接口:

http://localhost:8081/user/getCurrentUser

此时,会跳转到授权服务器的登录页面:

权限管理 springboot集成springSecurity Oauth2 JWT

登录成功访问到对应接口资源:

权限管理 springboot集成springSecurity Oauth2 JWT 

总结到此。文章来源地址https://www.toymoban.com/news/detail-412973.html

到了这里,关于权限管理 springboot集成springSecurity Oauth2 JWT的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Gateway+Springsecurity+OAuth2.0+JWT 实现分布式统一认证授权!

    目录 1. OAuth2.0授权服务 2. 资源服务 3. Gateway网关 4. 测试   在SpringSecurity+OAuth2.0 搭建认证中心和资源服务中心-CSDN博客 ​​​​​​ 基础上整合网关和JWT实现分布式统一认证授权。   大致流程如下: 1、客户端发出请求给网关获取令牌 2、网关收到请求,直接转发给授权服务

    2024年01月24日
    浏览(55)
  • SpringSecurity(二十四)--OAuth2:使用JWT和加密签名(下)非对称密钥加密

    由于上文对称密钥涉及到的内容比较多,所以这一节的非对称密钥加密拆开成这一节单独讲解。 所以大家尽量先阅读完上一章的内容后再浏览这一章内容会更好。 本节将实现OAuth2身份验证的一个示例,其中授权服务器和资源服务器会使用一个非对称密钥对来对令牌签名和验

    2024年02月16日
    浏览(49)
  • SpringSecurity学习(八)OAuth2.0、授权服务器、资源服务器、JWT令牌的使用

    OAuth2是一个认证协议,SpringSecurity对OAuth2协议提供了响应的支持,开发者可以非常方便的使用OAuth2协议。 简介 四种授权模式 Spring Security OAuth2 GitHub授权登录 授权服务器与资源服务器 使用JWT OAuth是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密资源

    2024年02月02日
    浏览(60)
  • springboot整合springsecurity+oauth2.0密码授权模式

    本文采用的springboot去整合springsecurity,采用oauth2.0授权认证,使用jwt对token增强。本文仅为学习记录,如有不足多谢提出。 OAuth 2.0是用于授权的行业标准协议。OAuth 2.0为简化客户端开发提供了特定的授权流,包括Web应用、桌面应用、移动端应用等。 Resource owner(资源拥有者)

    2024年02月04日
    浏览(61)
  • 12-SpringSecurity:通过OAuth2集成Github登录,字节跳动网络工程师的面试

    (1) 注册应用 在Github注册一个应用,生成 client-id , client-secret 。 注意这里的Home页: http://localhost:8080 ,以及回调地址: http://localhost:8080/login/oauth2/code/github (2) 配置 application.yml spring: security: oauth2: client: registration: github: client-id: client-secret: (3) 启动应用 为了看到登录

    2024年04月10日
    浏览(51)
  • SpringBoot3.0 + SpringSecurity6.0 +OAuth2 使用Github作为授权登录

    1.1 OAuth是什么 开放授权(OAuth)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。 OAuth允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供

    2024年02月11日
    浏览(46)
  • SpringBoot集成SpringSecurity从0到1搭建权限管理详细过程(认证+授权)

    最近工作需要给一个老系统搭建一套权限管理,选用的安全框架是SpringSecurity,基本上是结合业务从0到1搭建了一套权限管理,然后想着可以将一些核心逻辑抽取出来写一个权限通用Demo,特此记录下。 Spring Security是 Spring家族中的一个安全管理框架。相比与另外一个安全框架

    2024年02月04日
    浏览(42)
  • SpringSecurity实现角色权限控制(SpringBoot+SpringSecurity+JWT)

    通过 springboot整合jwt和security ,以用户名/密码的方式进行认证和授权。认证通过jwt+数据库的,授权这里使用了两种方式,分别是 SpringSecurity自带的hasRole方法+SecurityConfig 和 我们自定义的 permission+@PreAuthorize注解。 SpringSecurity中的几个重要组件: 1.SecurityContextHolder(class) 用来

    2024年02月05日
    浏览(44)
  • SpringBoot集成Oauth2.0(密码模式)

    Oauth2.0提供了四种认证方式: 授权码模式(authorization code)、 简化模式(implicit)、 密码模式(resource owner passwordcredentials)、 客户端模式(client credentials) Oauth2.0中的四个重要角色 OAauth2.0包括的角色 说明 资源拥有者 通常为用户,也可以是应用程序,即该资源的拥有者。

    2024年02月10日
    浏览(39)
  • SpringSecurity+OAuth2.0

    OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方移动应用或分享他们数据的所有内容。OAuth 在全世界得到广泛应用,目前的版本是 2.0 版。 简单

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包