資源服務器就是業務服務 如用戶服務,訂單服務等 第三方需要到資源服務器呼叫介面獲取資源
ResourceServerConfig
ResourceServerConfig是資源服務器的核心配置 用于驗證token 與網關配置相似
其中.antMatchers("/**").access("#oauth2.hasScope('user')") 需要oauth_client_details表的scope配合 意思是訪問所有資源 需要客戶端有scope需要有user

@Configuration
@EnableResourceServer // 標識為資源服務器,請求服務中的資源,就要帶著token過來,找不到token或token是無效訪問不了資源
@EnableGlobalMethodSecurity(prePostEnabled = true) // 開啟方法級別權限控制
public class ResourceServerConfig extends ResourceServerConfigurerAdapter implements CommandLineRunner {
private final static Logger logger = LoggerFactory.getLogger(ResourceServerConfig.class);
public static final String RESOURCE_ID = "user";
/**
* 權限不足回傳給前端json
*/
@Autowired
private CustomAccessDeniedHandlerConfig customAccessDeniedHandlerConfig;
@Autowired
private TokenStore tokenStore;
/**
* token無效回傳前段json
*/
@Autowired
private AuthExceptionEntryPointConfig authExceptionEntryPointConfig;
@Override
public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
// 當前資源服務器的資源id,認證服務會認證客戶端有沒有訪問這個資源id的權限,有則可以訪問當前服務
resources.tokenStore(tokenStore).resourceId(RESOURCE_ID)
// token無效例外的處理
.authenticationEntryPoint(authExceptionEntryPointConfig)
// 權限不足例外處理類
.accessDeniedHandler(customAccessDeniedHandlerConfig)
// 會話機制stateless開啟
.stateless(true);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http.sessionManagement()
// SpringSecurity不會使用也不會創建HttpSession實體 因為整個oauth2后使用token
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authorizeRequests()
// 開放swagger請求
.antMatchers("/swagger-ui.html", "/webjars/**", "/swagger-resources/**","/v2/**").permitAll()
// 所有請求,都需要有all范圍(scope)
.antMatchers("/**").access("#oauth2.hasScope('user')").
anyRequest().authenticated().and().csrf()
.disable();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
AuthExceptionEntryPointConfig,CustomAccessDeniedHandlerConfig
用于例外回傳前端json
@Component
public class CustomAccessDeniedHandlerConfig implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
response.setStatus(HttpStatus.OK.value());
response.setHeader("Content-Type", "application/json;charset=UTF-8");
try {
Result result = new Result(403, "權限不足");
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Component
public class AuthExceptionEntryPointConfig implements AuthenticationEntryPoint{
private final static Logger logger = LoggerFactory.getLogger(AuthExceptionEntryPointConfig.class);
@Value("${security.redirect-url}")
private String redirectUrl;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authException) {
Throwable cause = authException.getCause();
response.setStatus(HttpStatus.OK.value());
response.setHeader("Content-Type", "application/json;charset=UTF-8");
Result result;
try {
if (cause instanceof InvalidTokenException) {
result = new Result(402, "認證失敗,無效或過期token");
response.getWriter().write(new ObjectMapper().writeValueAsString(result));
} else {
result = new Result(401, "認證失敗,沒有攜帶token");
response.sendRedirect(redirectUrl);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
TokenConfig
不多說
@Configuration
public class TokenConfig{
/**
* 使用redis存盤
*/
@Autowired
private RedisConnectionFactory redisConnectionFactory;
@Bean
public TokenStore tokenStore() {
return new RedisTokenStore(redisConnectionFactory);
}
}
application.yml
那么小伙伴又問了 既然網關驗證token的有效性 那么資源服務器是不是就不用驗證啦 答案是否 因為不添加配置 會報錯 同樣需要在application中添加以下配置
其他配置也spirng boot為準 這里不多說
security:
oauth2:
client:
client-id: user-vue
client-secret: 1234
resource:
token-info-uri: http://localhost:8001/oauth/check_token
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/258465.html
標籤:其他
下一篇:“掃五福”的實作原理和技術詳解
