spring Security4 和 oauth2整合 注解+xml混合使用(基础运行篇)

Spring Security4 和 oauth2整合

最近项目中需要用到oauth2,到网上找了好多资料,全是乱七八糟的,东拼西凑,终于跑出来了一版,xml的方式太乱了,跑不了,还是用注解方式,并把一些关键配置提到xml中。

git地址:https://gitee.com/ffch/OauthUmp

spring Security4 和 oauth2整合 注解+xml混合使用(基础运行篇)
spring Security4 和 oauth2整合 注解+xml混合使用(进阶篇)
spring Security4 和 oauth2整合 注解+xml混合使用(授权码篇)
spring Security4 和 oauth2整合 注解+xml混合使用(注意事项篇)
spring Security4 和 oauth2整合 注解+xml混合使用(替换6位的授权码)
spring Security4 和 oauth2整合 注解+xml混合使用(替换用户名密码认证)
spring Security4 和 oauth2整合 注解+xml混合使用(验证码等额外数据验证)

网上已有的注解版方案(运行有问题,后面修正)

链接:http://www.yiibai.com/spring-security/secure-spring-rest-api-using-oauth2.html
这个链接没说是springmvc或者springboot使用,反正我是用springmvc使用了,可以用,我这里搬过来,同时写上自己的代码。后面会修改。

pom.xml


		4.0.5.RELEASE
		2.4
		4.0.1.RELEASE
	

	
		
			junit
			junit
			4.10
			test
		
		
			org.springframework
			spring-core
			${spring.version}
		
		
			org.springframework
			spring-aop
			${spring.version}
		

		
			org.springframework
			spring-aspects
			${spring.version}
		
		
			org.springframework
			spring-context
			${spring.version}
		
		
			org.springframework
			spring-beans
			${spring.version}
		
		
			org.springframework
			spring-context-support
			${spring.version}
		
		
			org.springframework
			spring-expression
			${spring.version}
		
		
			org.springframework
			spring-web
			${spring.version}
		
		
			org.springframework
			spring-webmvc
			${spring.version}
		
		
			org.springframework
			spring-context-support
			${spring.version}
		
		
			org.springframework
			spring-orm
			${spring.version}
		
		
			org.springframework
			spring-tx
			${spring.version}
		
		
			org.springframework
			spring-test
			${spring.version}
			test
			
				
					commons-logging
					commons-logging
				
			
		

		
		
			org.springframework.security
			spring-security-core
			${spring.security.version}
		
		
			org.springframework.security
			spring-security-web
			${spring.security.version}
		
		
			org.springframework.security
			spring-security-config
			${spring.security.version}
		
		
			org.springframework.security.oauth
			spring-security-oauth2
			2.1.0.RELEASE
		

		
		
			org.slf4j
			slf4j-log4j12
			1.7.5
		
		
			log4j
			log4j
			1.2.17
		
		

		
		
			javax.servlet
			jstl
			1.2
		

		
			commons-httpclient
			commons-httpclient
			3.1
		

		
		
			org.codehaus.jackson
			jackson-core-lgpl
			1.8.1
		
		
			org.codehaus.jackson
			jackson-mapper-lgpl
			1.8.1
		
		
			net.sf.json-lib
			json-lib
			${jsonlib.version}
			jdk15
		
		
			com.fasterxml.jackson.core
			jackson-annotations
			2.3.0
		
		
			com.fasterxml.jackson.core
			jackson-core
			2.3.1
		
		
			com.fasterxml.jackson.core
			jackson-databind
			2.3.3
		
		

		
		
			com.thoughtworks.xstream
			xstream
			1.4.10
		

		
		
			org.mybatis
			mybatis
			3.2.5
		
		
			org.mybatis
			mybatis-spring
			1.3.0
		
		
		
			com.alibaba
			druid
			1.0.20
		
		
			com.oracle
			ojdbc6
			11.2.2
		
		
		
			net.sf.ehcache
			ehcache
			2.10.2
		
	

ResourceServer

package com.yiibai.springmvc.security;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;

@Configuration
@EnableResourceServer
public class ResourceServerConfiguration extends ResourceServerConfigurerAdapter {

	private static final String RESOURCE_ID = "my_rest_api";
	
	@Override
	public void configure(ResourceServerSecurityConfigurer resources) {
		resources.resourceId(RESOURCE_ID).stateless(false);
	}

	@Override
	public void configure(HttpSecurity http) throws Exception {
		http.
		anonymous().disable()
		.requestMatchers().antMatchers("/user/**")
		.and().authorizeRequests()
		.antMatchers("/user/**").access("hasRole('ADMIN')")
		.and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());
	}

}

AuthorizationServer

package com.yiibai.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.approval.UserApprovalHandler;
import org.springframework.security.oauth2.provider.token.TokenStore;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {

	private static String REALM="MY_OAUTH_REALM";
	
	@Autowired
	private TokenStore tokenStore;

	@Autowired
	private UserApprovalHandler userApprovalHandler;

	@Autowired
	@Qualifier("authenticationManagerBean")
	private AuthenticationManager authenticationManager;

	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {

		clients.inMemory()
	        .withClient("my-trusted-client")
            .authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit")
            .authorities("ROLE_CLIENT", "ROLE_TRUSTED_CLIENT")
            .scopes("read", "write", "trust")
            .secret("secret")
            .accessTokenValiditySeconds(120).//Access token is only valid for 2 minutes.
            refreshTokenValiditySeconds(600);//Refresh token is only valid for 10 minutes.
	}

	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints.tokenStore(tokenStore).userApprovalHandler(userApprovalHandler)
				.authenticationManager(authenticationManager);
	}

	@Override
	public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
		oauthServer.realm(REALM+"/client");
	}

}

OAuth2SecurityConfiguration

package com.yiibai.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.approval.ApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenApprovalStore;
import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler;
import org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {

	@Autowired
	private ClientDetailsService clientDetailsService;
	
	@Autowired
    public void globalUserDetails(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
        .withUser("bill").password("abc123").roles("ADMIN").and()
        .withUser("bob").password("abc123").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
		http
		.csrf().disable()
		.anonymous().disable()
	  	.authorizeRequests()
	  	.antMatchers("/oauth/token").permitAll();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }


	@Bean
	public TokenStore tokenStore() {
		return new InMemoryTokenStore();
	}

	@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;
	}
	
}

MethodSecurityConfig

package com.yiibai.springmvc.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.oauth2.provider.expression.OAuth2MethodSecurityExpressionHandler;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
	@Autowired
	private OAuth2SecurityConfiguration securityConfig;

	@Override
	protected MethodSecurityExpressionHandler createExpressionHandler() {
		return new OAuth2MethodSecurityExpressionHandler();
	}
}

最后

这样就copy完了,不过springmvc不能用,需要在web.xml加上filter

  
    springSecurityFilterChain
    org.springframework.web.filter.DelegatingFilterProxy
  
  
    springSecurityFilterChain
    /*
  

这样就可以跑起来了,按照http://www.yiibai.com/spring-security/secure-spring-rest-api-using-oauth2.html提供的方法跑,不过你会发现,总是提示token错误。原因是tokenstore不一致。这样就不要用@Bean注解了,写在xml里,用@AutoWired就行。

xml配置tokenstore

	
	

配置完成后,就可以将OAuth2SecurityConfiguration文件中的tokenstore注掉。

//
//	@Bean
//	public TokenStore tokenStore() {
//		return new InMemoryTokenStore();
//	}

然后在文件AuthorizationServerConfiguration和ResourceServerConfiguration中的TokenStore @Autowired一下。

@Autowired
	private TokenStore tokenStore;

将clientdetails提到xml中

clientdetails写在代码里,不方便替换,可以写到配置文件中。


		
			
				
				
			
		

	

	
		
		
		
		
		
			
				read
				write
				trust
			
		
		
			
				password
				authorization_code
				refresh_token
				implicit
			
		
		
			
				
					
				
				
					
				
			
		
	
	
		
		
		
		
		
			
				read
				write
				trust
			
		
		
			
				password
				authorization_code
				refresh_token
				implicit
			
		
		
			
				
					
				
				
					
				
			
		
	

下一篇介绍如何替换其他东西和一些页面问题。

你可能感兴趣的:(spring,oauth2)