[置顶] 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);
	}

}




你可能感兴趣的:([置顶] spring oauth2.0入门(实战))