我在一个应用程序中配置资源和授权服务器。我用弹簧安全的oauth2,与资源所有者密码凭据。我可以设置服务器端的基本身份验证?我并不想这样做的前端。我不知道我需要显示的代码的一部分...当我想收到的令牌,我需要在邮递员输入:我可以在服务器端配置呢?
授权服务器:
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private DataSource dataSource;
@Autowired
private TokenStore tokenStore;
@Autowired
private JwtAccessTokenConverter jwtTokenEnhancer;
@Autowired
private UserApprovalHandler userApprovalHandler;
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.jdbc(dataSource);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer security) {
security.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.tokenStore(tokenStore).tokenEnhancer(jwtTokenEnhancer).userApprovalHandler(userApprovalHandler)
.authenticationManager(authenticationManager)
.pathMapping("/oauth/token", "/login");
}
}
资源服务器:
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
private static final String RESOURCE_ID = "resource_id";
@Override
public void configure(ResourceServerSecurityConfigurer resources) {
resources.resourceId(RESOURCE_ID).stateless(false);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.cors().and().csrf().disable()
.authorizeRequests()
.antMatchers("/swagger-ui.html#").permitAll()
.antMatchers("/").authenticated()
.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
}
}
安全配置:
@Configuration
@EnableWebSecurity(debug = true)
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private ClientDetailsService clientDetailsService;
@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(10);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
@Bean
public TokenStore tokenStore() {
return new JwtTokenStore(jwtTokenEnhancer());
}
@Bean
protected JwtAccessTokenConverter jwtTokenEnhancer() {
converter.setSigningKey("Demo-Key-1");
return converter;
}
@Bean
@Autowired
public TokenStoreUserApprovalHandler userApprovalHandler(TokenStore tokenStore) {
TokenStoreUserApprovalHandler handler = new TokenStoreUserApprovalHandler();
handler.setTokenStore(tokenStore);
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
handler.setClientDetailsService(clientDetailsService);
return handler;
}
@Bean
@Autowired
public ApprovalStore approvalStore(TokenStore tokenStore) throws Exception {
TokenApprovalStore store = new TokenApprovalStore();
store.setTokenStore(tokenStore);
return store;
}
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
protected void configure(final HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**").permitAll()
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
.and().cors().and().csrf().disable();
}
}
这个答案是伴随着complete and working sample。
也许你是biting off more than you can chew这里?
例如:
.antMatchers(HttpMethod.OPTIONS, "/oauth/token").permitAll()
该/oauth/token
端点必须受到保护。这是授权服务器发出令牌验证的客户端在端点上。如果你打开它的系统可能会失败,并NullpointerException
或其他异常,然而,上述配置选项表明,也许你是一个有点困惑了OAuth2是如何工作的。
我建议是先充分了解授权服务器与资源服务器。你绝对可以将二者结合起来,但是他们有很不同的端点。
授权服务器 - 典型的端点
/oauth/token - issues tokens
/oauth/authorize - issues authorization codes
/introspect - validates a token and returns token claims in a known format
资源服务器 - 这些将是你的应用程序的端点,要求Bearer
令牌,例如
/account/123/debit
和这些端点希望有一个授权头一个无状态的请求
Authorization: Bearer <token value here>
一种用于资源服务器控制器是这样的:
@PreAuthorize("hasRole('your-scope-role')")
@RequestMapping(value = "/hello")
@ResponseBody
public String hello(Principal principal) {
return "Hello to " + principal.getName();
}
随时都可以查阅,我已经为您创建的simple project。
除此之外,我还建议在OAuth2 and OpenID Connect视频
在我的示例,我已经配置了这样的clients:
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
InMemoryClientDetailsService clientDetails = new InMemoryClientDetailsService();
BaseClientDetails client = new BaseClientDetails(
"testclient",
null,
"testscope,USER,ADMIN",
"password",
null
);
client.setClientSecret(passwordEncoder.encode("secret"));
clientDetails.setClientDetailsStore(
Collections.singletonMap(
client.getClientId(),
client
)
);
clients.withClientDetails(clientDetails);
}
看看这个简单的测试情况下,客户端使用HTTP的基本身份验证:
mvc.perform(
post("/oauth/token")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.param("username", "admin")
.param("password", "password")
.param("grant_type", "password")
.param("response_type", "token")
.param("client_id", "testclient")
.header("Authorization", "Basic " + Base64.encodeBase64String("testclient:secret".getBytes()))
这是客户端身份验证,使用HTTP的基本方法:
.header("Authorization", "Basic " + Base64.encodeBase64String("testclient:secret".getBytes()))