spring-security-oauth2注解详解
spring-security-oauth2支持的注解有:
1.EnableOAuth2Client
適用于使用spring security,并且想從Oauth2認證服務器來獲取授權的web應用環(huán)境代碼中,它啟用了一個Oauth2 客戶端配置。為了更好的利用這個特性,需要在客戶端應用中的DelegatingFilterProxy(代理一個名為oauth2ClientContextFilter)增加一個servlet filter。當filter配置到client app時,可以使用注解@AccessTokenRequest提供的另一個bean來創(chuàng)建一個Oauth2RequestTemplate。示例:
@Configuration@EnableOAuth2Clientpublic class RemoteResourceConfiguration {@Beanpublic OAuth2RestOperations restTemplate(OAuth2ClientContext oauth2ClientContext) {return new OAuth2RestTemplate(remote(), oauth2ClientContext);}}Client App使用client credential授權,不需要AccessTokenRequest或者域內RestOperation(對app來說,狀態(tài)是全局的),但在需要時仍然使用filter來觸發(fā)OAuth2RestOperation來獲取token。使用密碼授權的app需要在RestOperation動作之前為OAuth2ProtectedResouceDetail設置認證屬性,這就是說,resouce detail 本身也需要session(假設系統(tǒng)中有多個用戶)。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(OAuth2ClientConfiguration.class) public @interface EnableOAuth2Client {}?
實現(xiàn)OAuth2ClientConfiguration
@Configuration public class OAuth2ClientConfiguration {@Beanpublic OAuth2ClientContextFilter oauth2ClientContextFilter() {OAuth2ClientContextFilter filter = new OAuth2ClientContextFilter();return filter;}@Bean@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)protected AccessTokenRequest accessTokenRequest(@Value("#{request.parameterMap}")Map<String, String[]> parameters, @Value("#{request.getAttribute('currentUri')}")String currentUri) {DefaultAccessTokenRequest request = new DefaultAccessTokenRequest(parameters);request.setCurrentUri(currentUri);return request;}@Configurationprotected static class OAuth2ClientContextConfiguration {@Resource@Qualifier("accessTokenRequest")private AccessTokenRequest accessTokenRequest;@Bean@Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)public OAuth2ClientContext oauth2ClientContext() {return new DefaultOAuth2ClientContext(accessTokenRequest);}}}2.?EnableAuthorizationServer
工具方法,用來在當前應用context里(必須是一個DispatcherServlet context)開啟一個授權server(例如AuthorizationEndpoint)和一個TokenEndpoint。server的多個屬性可以通過自定義AuthorizationServerConfigurer類型(如AuthorizationServerConfigurerAdapter的擴展)的Bean來定制。通過正常使用spring security的特色EnableWebSecurity,用戶負責保證授權Endpoint(/oauth/authorize)的安全,但Token Endpoint(/oauth/token)將自動使用http basic的客戶端憑證來保證安全。通過一個或者多個AuthorizationServerConfigurer提供一個ClientDetailService來注冊client(必須)。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AuthorizationServerEndpointsConfiguration.class, AuthorizationServerSecurityConfiguration.class}) public @interface EnableAuthorizationServer {}2.1?AuthorizationServerEndpointsConfiguration
private AuthorizationServerEndpointsConfigurer endpoints = new AuthorizationServerEndpointsConfigurer();@Autowiredprivate ClientDetailsService clientDetailsService;@Autowiredprivate List<AuthorizationServerConfigurer> configurers = Collections.emptyList();@PostConstructpublic void init() {for (AuthorizationServerConfigurer configurer : configurers) {try {configurer.configure(endpoints);} catch (Exception e) {throw new IllegalStateException("Cannot configure enpdoints", e);}}endpoints.setClientDetailsService(clientDetailsService);}?
?
@Componentprotected static class TokenKeyEndpointRegistrar implements BeanDefinitionRegistryPostProcessor {private BeanDefinitionRegistry registry;@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {String[] names = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory,JwtAccessTokenConverter.class, false, false);if (names.length > 0) {BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(TokenKeyEndpoint.class);builder.addConstructorArgReference(names[0]);registry.registerBeanDefinition(TokenKeyEndpoint.class.getName(), builder.getBeanDefinition());}}@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {this.registry = registry;}}2.2?AuthorizationServerSecurityConfiguration
@Configuration @Order(0) @Import({ ClientDetailsServiceConfiguration.class, AuthorizationServerEndpointsConfiguration.class }) public class AuthorizationServerSecurityConfiguration extends WebSecurityConfigurerAdapter {@Autowiredprivate List<AuthorizationServerConfigurer> configurers = Collections.emptyList();@Autowiredprivate ClientDetailsService clientDetailsService;@Autowiredprivate AuthorizationServerEndpointsConfiguration endpoints;@Autowiredpublic void configure(ClientDetailsServiceConfigurer clientDetails) throws Exception {for (AuthorizationServerConfigurer configurer : configurers) {configurer.configure(clientDetails);}}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {// Over-riding to make sure this.disableLocalConfigureAuthenticationBldr = false// This will ensure that when this configurer builds the AuthenticationManager it will not attempt// to find another 'Global' AuthenticationManager in the ApplicationContext (if available),// and set that as the parent of this 'Local' AuthenticationManager.// This AuthenticationManager should only be wired up with an AuthenticationProvider// composed of the ClientDetailsService (wired in this configuration) for authenticating 'clients' only. }@Overrideprotected void configure(HttpSecurity http) throws Exception {AuthorizationServerSecurityConfigurer configurer = new AuthorizationServerSecurityConfigurer();FrameworkEndpointHandlerMapping handlerMapping = endpoints.oauth2EndpointHandlerMapping();http.setSharedObject(FrameworkEndpointHandlerMapping.class, handlerMapping);configure(configurer);http.apply(configurer);String tokenEndpointPath = handlerMapping.getServletPath("/oauth/token");String tokenKeyPath = handlerMapping.getServletPath("/oauth/token_key");String checkTokenPath = handlerMapping.getServletPath("/oauth/check_token");if (!endpoints.getEndpointsConfigurer().isUserDetailsServiceOverride()) {UserDetailsService userDetailsService = http.getSharedObject(UserDetailsService.class);endpoints.getEndpointsConfigurer().userDetailsService(userDetailsService);}// @formatter:off http.authorizeRequests().antMatchers(tokenEndpointPath).fullyAuthenticated().antMatchers(tokenKeyPath).access(configurer.getTokenKeyAccess()).antMatchers(checkTokenPath).access(configurer.getCheckTokenAccess()).and().requestMatchers().antMatchers(tokenEndpointPath, tokenKeyPath, checkTokenPath).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);// @formatter:onhttp.setSharedObject(ClientDetailsService.class, clientDetailsService);}protected void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {for (AuthorizationServerConfigurer configurer : configurers) {configurer.configure(oauthServer);}}}?3.?EnableResourceServer
Oauth2 資源服務器的便利方法,開啟了一個spring security的filter,這個filter通過一個Oauth2的token進行認證請求。使用者應該增加這個注解,并提供一個ResourceServerConfigurer類型的Bean(例如通過ResouceServerConfigurerAdapter)來指定資源(url路徑和資源id)的細節(jié)。為了利用這個filter,你必須在你的應用中的某些地方EnableWebSecurity,或者使用這個注解的地方,或者其他別的地方。
這個注解創(chuàng)建了一個WebSecurityConfigurerAdapter,且自帶了硬編碼的order=3.在spring中,由于技術原因不能立即改變order的順序,因此你必須在你的spring應用中避免使用order=3的其他WebSecurityConfigurerAdapter。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(ResourceServerConfiguration.class) public @interface EnableResourceServer {}ResourceServerConfiguration
@Overrideprotected void configure(HttpSecurity http) throws Exception { ResourceServerSecurityConfigurer resources = new ResourceServerSecurityConfigurer();ResourceServerTokenServices services = resolveTokenServices();if (services != null) {resources.tokenServices(services);}else {if (tokenStore != null) {resources.tokenStore(tokenStore);}else if (endpoints != null) {resources.tokenStore(endpoints.getEndpointsConfigurer().getTokenStore());}}if (eventPublisher != null) {resources.eventPublisher(eventPublisher);}for (ResourceServerConfigurer configurer : configurers) {configurer.configure(resources);}// @formatter:offhttp.authenticationProvider(new AnonymousAuthenticationProvider("default"))// N.B. exceptionHandling is duplicated in resources.configure() so that// it works .exceptionHandling().accessDeniedHandler(resources.getAccessDeniedHandler()).and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().csrf().disable();// @formatter:on http.apply(resources);if (endpoints != null) {// Assume we are in an Authorization Serverhttp.requestMatcher(new NotOAuthRequestMatcher(endpoints.oauth2EndpointHandlerMapping()));}for (ResourceServerConfigurer configurer : configurers) {// Delegates can add authorizeRequests() here configurer.configure(http);}if (configurers.isEmpty()) {// Add anyRequest() last as a fall back. Spring Security would// replace an existing anyRequest() matcher with this one, so to// avoid that we only add it if the user hasn't configured anything. http.authorizeRequests().anyRequest().authenticated();}}ResourceServerSecurityConfigurer
重新的兩個方法
1.init
@Overridepublic void init(HttpSecurity http) throws Exception {registerDefaultAuthenticationEntryPoint(http);}@SuppressWarnings("unchecked")private void registerDefaultAuthenticationEntryPoint(HttpSecurity http) {ExceptionHandlingConfigurer<HttpSecurity> exceptionHandling = http.getConfigurer(ExceptionHandlingConfigurer.class);if (exceptionHandling == null) {return;}ContentNegotiationStrategy contentNegotiationStrategy = http.getSharedObject(ContentNegotiationStrategy.class);if (contentNegotiationStrategy == null) {contentNegotiationStrategy = new HeaderContentNegotiationStrategy();}MediaTypeRequestMatcher preferredMatcher = new MediaTypeRequestMatcher(contentNegotiationStrategy,MediaType.APPLICATION_ATOM_XML, MediaType.APPLICATION_FORM_URLENCODED, MediaType.APPLICATION_JSON,MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA,MediaType.TEXT_XML);preferredMatcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));exceptionHandling.defaultAuthenticationEntryPointFor(postProcess(authenticationEntryPoint), preferredMatcher);}2.configure
@Overridepublic void configure(HttpSecurity http) throws Exception {AuthenticationManager oauthAuthenticationManager = oauthAuthenticationManager(http);resourcesServerFilter = new OAuth2AuthenticationProcessingFilter();resourcesServerFilter.setAuthenticationEntryPoint(authenticationEntryPoint);resourcesServerFilter.setAuthenticationManager(oauthAuthenticationManager);if (eventPublisher != null) {resourcesServerFilter.setAuthenticationEventPublisher(eventPublisher);}if (tokenExtractor != null) {resourcesServerFilter.setTokenExtractor(tokenExtractor);}resourcesServerFilter = postProcess(resourcesServerFilter);resourcesServerFilter.setStateless(stateless);// @formatter:off http.authorizeRequests().expressionHandler(expressionHandler).and().addFilterBefore(resourcesServerFilter, AbstractPreAuthenticatedProcessingFilter.class).exceptionHandling().accessDeniedHandler(accessDeniedHandler).authenticationEntryPoint(authenticationEntryPoint);// @formatter:on}其中OAuth2AuthenticationProcessingFilter:A pre-authentication filter for OAuth2 protected resources. Extracts an OAuth2 token from the incoming request and?uses it to populate the Spring Security context with an {@link OAuth2Authentication} (if used in conjunction with an{@link OAuth2AuthenticationManager}).
?
轉載于:https://www.cnblogs.com/davidwang456/p/6480681.html
總結
以上是生活随笔為你收集整理的spring-security-oauth2注解详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一张图了解javaJwt
- 下一篇: 使用Spring Boot Actuat