关于springsecurity:SpringSecurityOauth2搭建资源服务

8次阅读

共计 5444 个字符,预计需要花费 14 分钟才能阅读完成。

前言

之前写过应用 springsecurity 搭建认证服务 SpringSecurity+Oauth2:明码受权模式获取 Token(MongoDB+JWT),这篇则写对于如何搭建资源服务,只有验证通过的 token 能力拜访。

操作

1、配置 Pom.xml 援用 spring-cloud-securityoauth2的 jar 包
2、配置主类@EnableResourceServer 注解,开启资源服务
3、创立JWTTokenStoreConfig 类,配置和解析 token
4、创立 ResourceServerConfiguration 类配置拜访权限以及自定义异样
5、自定义springsecurity 异样信息 ( 留神:认证和资源服务的自定义异样是对立的没有区别,上面会阐明)

1、配置 Pom.xml 援用 spring-cloud-securityoauth2的 jar 包

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-oauth2</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-security</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

2、配置主类 @EnableResourceServer 注解,开启资源服务

@SpringBootApplication
// 资源爱护服务
@EnableResourceServer
// 服务发现
@EnableDiscoveryClient
@EnableFeignClients
@RefreshScope
public class Xxxx {
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
    }

    public static void main(String[] args) {SpringApplication.run(Xxxx.class, args);
    }
}

3、创立 JWTTokenStoreConfig 类,配置和解析 token

@Configuration
public class JWTTokenStoreConfig {

    @Autowired
    private ServiceConfig serviceConfig;

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

    //JWT
    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        defaultTokenServices.setSupportRefreshToken(true);
        return defaultTokenServices;
    }


    //JWT
    // 从配置文件中获取 jwt key,而后本人解析 token 是否无效,@Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(serviceConfig.getJwtSigningKey());
        return converter;
    }

}

4、创立 ResourceServerConfiguration 类配置拜访权限以及自定义异样

@Configuration
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter{

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {OAuth2AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        authenticationEntryPoint.setExceptionTranslator(new CustomOAuthWebResponseExceptionTranslator());
        resources.authenticationEntryPoint(authenticationEntryPoint);

        OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler = new OAuth2AccessDeniedHandler();
        oAuth2AccessDeniedHandler.setExceptionTranslator(new CustomOAuthWebResponseExceptionTranslator());
        resources.accessDeniedHandler(oAuth2AccessDeniedHandler);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {http.authorizeRequests()
                // 放开 /sendRegisterEmailMessage,不须要校验 token
                .antMatchers("/websocket/**").permitAll()
                .antMatchers("/info/**").permitAll()
                .anyRequest().authenticated();
    }
}

5、自定义 springsecurity 异样信息

创立 CustomOAuthException

@JsonSerialize(using = CustomOAuthExceptionSerializer.class)
public class CustomOAuthException extends OAuth2Exception {private static Logger log = LoggerFactory.getLogger(CustomOAuthException.class);

    private String oAuth2ErrorCode;

    private int httpErrorCode;

    public CustomOAuthException(String msg, String oAuth2ErrorCode, int httpErrorCode) {super(msg);
        this.oAuth2ErrorCode = oAuth2ErrorCode;
        this.httpErrorCode = httpErrorCode;
    }

}

创立 CustomOAuthExceptionSerializer

public class CustomOAuthExceptionSerializer extends StdSerializer<CustomOAuthException> {private static Logger log = LoggerFactory.getLogger(CustomOAuthExceptionSerializer.class);

    protected CustomOAuthExceptionSerializer() {super(CustomOAuthException.class);
    }

    @Override
    public void serialize(CustomOAuthException e, JsonGenerator generator, SerializerProvider serializerProvider) throws IOException {generator.writeStartObject();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        generator.writeObjectField("error",e.getOAuth2ErrorCode());
        generator.writeObjectField("status", e.getHttpErrorCode());
        generator.writeObjectField("message", e.getMessage());
        generator.writeObjectField("path", request.getServletPath());
        generator.writeObjectField("timestamp", (new Date()).getTime());
        if (e.getAdditionalInformation() != null) {for (Map.Entry<String, String> entry : e.getAdditionalInformation().entrySet()) {String key = entry.getKey();
                String add = entry.getValue();
                generator.writeObjectField(key, add);
            }
        }
        generator.writeEndObject();}
}

创立 CustomOAuthWebResponseExceptionTranslator

@Component
public class CustomOAuthWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {private ThrowableAnalyzer throwableAnalyzer = new DefaultThrowableAnalyzer();
    private static Logger log = LoggerFactory.getLogger(CustomOAuthWebResponseExceptionTranslator.class);

    @Override
    public ResponseEntity<OAuth2Exception> translate(Exception e) throws Exception {ResponseEntity<OAuth2Exception> translate = super.translate(e);
        OAuth2Exception body = translate.getBody();

        CustomOAuthException customOauthException = new CustomOAuthException(body.getMessage(),body.getOAuth2ErrorCode(),body.getHttpErrorCode());
        ResponseEntity<OAuth2Exception> response = new ResponseEntity<>(customOauthException, translate.getHeaders(), translate.getStatusCode());
        return response;
    }
}

最初如果用户名或明码谬误则返回上面的错误信息:

{
  timestamp: 1658149719489,
  path: '/oauth/token',
  error: 'invalid_request',
  message: '用户名或明码谬误'
  status: 400
}

如果 token 谬误则返回上面的错误信息:

{
  timestamp: 1658149719489,
  path: '/oauth/token',
  error: 'invalid_request',
  message: 'token 谬误或过期'
  status: 400
}

如果 refresh_token 谬误则返回上面的错误信息:

{
  timestamp: 1658149719489,
  path: '/oauth/token',
  error: 'invalid_request',
  message: 'refresh_token 谬误或过期'
  status: 400
}

资源服务的目录构造

认证服务的目录构造

总结

1、springsecurity 自带的异样信息不合乎本人的需要的时候就要自定义返回错误信息
2、错误信息返回的错误码如果是 401 那么照样返回 401,如果感觉 401 不太好能够自行设置

援用

SpringBoot Security 的自定义异样

正文完
 0