spring oauth2.0授權伺服器配置
1.首先spring security基本配置
-
public class ServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
-
......
-
@Override
-
public void onStartup(ServletContext servletContext) throws ServletException {
-
super.onStartup(servletContext);
-
/** UrlRewriteFilter **/
-
/*
-
* servletContext.addFilter("UrlRewriteFilter",
-
* UrlRewriteFilter.class).addMappingForUrlPatterns(null, false, "/*");
-
*/
-
DelegatingFilterProxy filter = new DelegatingFilterProxy("springSecurityFilterChain");
-
filter.setContextAttribute("org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcher");
-
servletContext.addFilter("springSecurityFilterChain", filter).addMappingForUrlPatterns(null, false, "/*");
-
}
-
}
-
@Configuration
-
@EnableWebSecurity
-
@Order(2)
-
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
-
@Autowired
-
private UserDetailsService myUserDetailsService;
-
@Override
-
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
-
// auth.inMemoryAuthentication().withUser("marissa").password("koala").roles("USER").and().withUser("paul")
-
// .password("emu").roles("USER");
-
auth.userDetailsService(myUserDetailsService);
-
}
-
@Override
-
public void configure(WebSecurity web) throws Exception {
-
web.ignoring().antMatchers("/webjars/**", "/images/**", "/oauth/uncache_approvals", "/oauth/cache_approvals");
-
}
-
@Override
-
protected UserDetailsService userDetailsService() {
-
return myUserDetailsService;
-
}
-
@Override
-
@Bean
-
public AuthenticationManager authenticationManagerBean() throws Exception {
-
return super.authenticationManagerBean();
-
}
-
@Override
-
protected void configure(HttpSecurity http) throws Exception {
-
System.out.println("==============SecurityConfiguration.configure(HttpSecurity http)");
-
// @formatter:off
-
http
-
.authorizeRequests()
-
.antMatchers("/login.jsp").permitAll()
-
.anyRequest().hasRole("USER")
-
.and()
-
.exceptionHandling()
-
.accessDeniedPage("/login.jsp?authorization_error=true")
-
.and()
-
// TODO: put CSRF protection back into this endpoint
-
.csrf()
-
.requireCsrfProtectionMatcher(new AntPathRequestMatcher("/oauth/authorize"))
-
.disable()
-
.logout()
-
.logoutUrl("/logout")
-
.logoutSuccessUrl("/login.jsp")
-
.and()
-
.formLogin()
-
.loginProcessingUrl("/login")
-
.failureUrl("/login.jsp?authentication_error=true")
-
.loginPage("/login.jsp");
-
// @formatter:on
-
}
-
}
2.配置oauth
-
@Configuration
-
public class OAuth2ServerConfig {
-
@Configuration
-
@EnableResourceServer
-
@Order(6)
-
protected static class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {
-
@Override
-
public void configure(ResourceServerSecurityConfigurer resources) {
-
resources.resourceId(ResourcesIDs.USER_RESOURCE_ID).stateless(false);
-
}
-
@Override
-
public void configure(HttpSecurity http) throws Exception {
-
System.out.println("====================ResourceServerConfiguration.configure(HttpSecurity http)");
-
// @formatter:off
-
http
-
// Since we want the protected resources to be accessible in the UI as well we need
-
// session creation to be allowed (it's disabled by default in 2.0.6)
-
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
-
.and()
-
.requestMatchers()
-
.antMatchers("/user/**")
-
.and()
-
.authorizeRequests()
-
.antMatchers("/user/profile").access("#oauth2.hasScope('read') or (!#oauth2.isOAuth() and hasRole('ROLE_USER'))");
-
// @formatter:on
-
}
-
}
-
@Configuration
-
@EnableAuthorizationServer
-
protected static class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
-
@Autowired
-
@Qualifier("myClientDetailsService")
-
private ClientDetailsService clientDetailsService;
-
@Autowired
-
private TokenStore tokenStore;
-
@Autowired
-
private UserApprovalHandler userApprovalHandler;
-
@Autowired
-
@Qualifier("authenticationManagerBean")
-
private AuthenticationManager authenticationManager;
-
@Override
-
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
-
clients.withClientDetails(clientDetailsService);
-
}
-
@Override
-
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
-
endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
-
.authenticationManager(authenticationManager);
-
/*
-
* .pathMapping("/oauth/authorize", "/oauth2/authorize")
-
* .pathMapping("/oauth/token", "/oauth2/token");
-
*/
-
// 以上的註釋掉的是用來改變配置的
-
}
-
@Override
-
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
-
// oauthServer.realm("sparklr2/client");
-
oauthServer.allowFormAuthenticationForClients();
-
}
-
@Bean
-
public TokenStore tokenStore() {
-
return new InMemoryTokenStore();
-
}
-
}
-
/**
-
* @author admin
-
*
-
* some bean denfinition
-
*
-
*/
-
@Configuration
-
protected static class Stuff {
-
@Autowired
-
@Qualifier("myClientDetailsService")
-
private ClientDetailsService clientDetailsService;
-
@Autowired
-
private TokenStore tokenStore;
-
@Bean
-
public ApprovalStore approvalStore() throws Exception {
-
TokenApprovalStore store = new TokenApprovalStore();
-
store.setTokenStore(tokenStore);
-
return store;
-
}
-
@Bean
-
@Lazy
-
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
-
public MyUserApprovalHandler userApprovalHandler() throws Exception {
-
MyUserApprovalHandler handler = new MyUserApprovalHandler();
-
handler.setApprovalStore(approvalStore());
-
handler.setRequestFactory(new DefaultOAuth2RequestFactory(clientDetailsService));
-
handler.setClientDetailsService(clientDetailsService);
-
handler.setUseApprovalStore(true);
-
return handler;
-
}
-
}
以上是基於註解配置的
一定注意: ResourceServerConfiguration 和 SecurityConfiguration上配置的順序, SecurityConfiguration一定要在ResourceServerConfiguration 之前,因為spring實現安全是通過新增過濾器(Filter)來實現的,基本的安全過濾應該在oauth過濾之前, 所以在SecurityConfiguration設定@Order(2), 在ResourceServerConfiguration上設定@Order(6)
其它類:
MyUserApprovalHandler.java
-
public class MyUserApprovalHandler extends ApprovalStoreUserApprovalHandler {
-
private boolean useApprovalStore = true;
-
private ClientDetailsService clientDetailsService;
-
/**
-
* Service to load client details (optional) for auto approval checks.
-
*
-
* @param clientDetailsService
-
* a client details service
-
*/
-
public void setClientDetailsService(ClientDetailsService clientDetailsService) {
-
this.clientDetailsService = clientDetailsService;
-
super.setClientDetailsService(clientDetailsService);
-
}
-
/**
-
* @param useApprovalStore
-
* the useTokenServices to set
-
*/
-
public void setUseApprovalStore(boolean useApprovalStore) {
-
this.useApprovalStore = useApprovalStore;
-
}
-
/**
-
* Allows automatic approval for a white list of clients in the implicit
-
* grant case.
-
*
-
* @param authorizationRequest
-
* The authorization request.
-
* @param userAuthentication
-
* the current user authentication
-
*
-
* @return An updated request if it has already been approved by the current
-
* user.
-
*/
-
@Override
-
public AuthorizationRequest checkForPreApproval(AuthorizationRequest authorizationRequest,
-
Authentication userAuthentication) {
-
boolean approved = false;
-
// If we are allowed to check existing approvals this will short circuit
-
// the decision
-
if (useApprovalStore) {
-
authorizationRequest = super.checkForPreApproval(authorizationRequest, userAuthentication);
-
approved = authorizationRequest.isApproved();
-
} else {
-
if (clientDetailsService != null) {
-
Collection<String> requestedScopes = authorizationRequest.getScope();
-
try {
-
ClientDetails client = clientDetailsService
-
.loadClientByClientId(authorizationRequest.getClientId());
-
for (String scope : requestedScopes) {
-
if (client.isAutoApprove(scope)) {
-
approved = true;
-
break;
-
}
-
}
-
} catch (ClientRegistrationException e) {
-
}
-
}
-
}
-
authorizationRequest.setApproved(approved);
-
return authorizationRequest;
-
}
-
}
MyClientDetailsService.java
-
@Service
-
public class MyClientDetailsService implements ClientDetailsService {
-
private ClientDetailsService clientDetailsService;
-
@PostConstruct
-
public void init() {
-
InMemoryClientDetailsServiceBuilder inMemoryClientDetailsServiceBuilder = new InMemoryClientDetailsServiceBuilder();
-
// @formatter:off
-
inMemoryClientDetailsServiceBuilder.
-
withClient("tonr")
-
.resourceIds(ResourcesIDs.USER_RESOURCE_ID)
-
.authorizedGrantTypes("authorization_code", "implicit")
-
.authorities("ROLE_CLIENT")
-
.scopes("read", "write")
-
.secret("secret")
-
.and()
-
.withClient("tonr-with-redirect")
-
.resourceIds(ResourcesIDs.USER_RESOURCE_ID)
-
.authorizedGrantTypes("authorization_code", "implicit")
-
.authorities("ROLE_CLIENT")
-
.scopes("read", "write")
-
.secret("secret")
-
// .redirectUris(tonrRedirectUri)
-
.and()
-
.withClient("my-client-with-registered-redirect")
-
.resourceIds(ResourcesIDs.USER_RESOURCE_ID)
-
.authorizedGrantTypes("authorization_code", "client_credentials")
-
.authorities("ROLE_CLIENT")
-
.scopes("read", "trust")
-
.redirectUris("http://anywhere?key=value")
-
.and()
-
.withClient("my-trusted-client")
-
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
-
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
-
.scopes("read", "write", "trust")
-
.accessTokenValiditySeconds(60)
-
.and()
-
.withClient("my-trusted-client-with-secret")
-
.authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
-
.authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
-
.scopes("read", "write", "trust")
-
.secret("somesecret")
-
.and()
-
.withClient("my-less-trusted-client")
-
.authorizedGrantTypes("authorization_code", "implicit")
-
.authorities("ROLE_CLIENT")
-
.scopes("read", "write", "trust")
-
.and()
-
.withClient("my-less-trusted-autoapprove-client")
-
.authorizedGrantTypes("implicit")
-
.authorities("ROLE_CLIENT")
-
.scopes("read", "write", "trust")
-
.autoApprove(true);
-
// @formatter:on
-
try {
-
clientDetailsService = inMemoryClientDetailsServiceBuilder.build();
-
} catch (Exception e) {
-
// TODO Auto-generated catch block
-
e.printStackTrace();
-
}
-
}
-
@Override
-
public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException {
-
System.out.println("loadClientByClientId:" + clientId + " ----------------------");
-
return clientDetailsService.loadClientByClientId(clientId);
-
}
-
}