Spring Security OAuth2 實現SSO
阿新 • • 發佈:2018-12-26
SSO即Single Sign-On,單點登入,即授權伺服器形式,通過在一個網站上登入完後,給予過授權的就可以直接用這個帳號資訊登入了,類似於qq微信登入其他APP。
本篇文章,將利用Spring Security實現簡單的單點登入中需要的,認證伺服器和客戶端。
SSO伺服器
首先實現一個SSO伺服器,下面是基本的pom檔案:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId >
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
啟動main方法:
這裡面主要用EnableResourceServer來開啟資源伺服器。
@SpringBootApplication
@EnableResourceServer
public class SsoServerApplication {
public static void main(String[] args) {
SpringApplication.run(SsoServerApplication.class, args);
}
}
下面再分別介紹Spring Security和OAuth2的Config類:
以下是OAuth2的Config類:
//Auth2的配置檔案
@Configuration
@EnableAuthorizationServer
public class Auth2Config extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager; //使用預設的認證管家
@Override
public void configure(final AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()") //能夠獲取token的
.checkTokenAccess("isAuthenticated()"); //檢測是否認證
}
@Override
public void configure(final ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("SampleClientId") //接受的clientId
.secret("secret") //預設secret
.authorizedGrantTypes("authorization_code") //授權模式
.scopes("user_info") //範圍,只獲取使用者認證。
.autoApprove(true);
}
@Override
public void configure(final AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
Auth2Config
定義了一些Auth2的資訊,例如對名為SampleClientId
的註冊,以及對認證規則的定義:
oauthServer.tokenKeyAccess("permitAll()") //能夠獲取token的
.checkTokenAccess("isAuthenticated()"); //檢測是否認證
以下是Spring Security的配置:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.requestMatchers()
.antMatchers("/login", "/oauth/authorize")
.and()
.authorizeRequests() //請求授權,後面的需要授權。
.anyRequest()
.authenticated()
.and()
.formLogin() //登入表單開放給所有人,預設的登入表單。
.permitAll();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { // @formatter:off
auth.parentAuthenticationManager(authenticationManager)
.inMemoryAuthentication()
.withUser("anla7856") //模擬一個註冊使用者名稱
.password("123456")
.roles("USER");
}
}
下面是application.yml配置:
server:
port: 8080
context-path: /auth
security:
basic:
enabled: false #阻止基本認證
下面是sso客戶端程式碼:
SSO客戶端
sso客戶端,也是基於Spring Security實現,下面是其pom檔案:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
</dependency>
再看看啟動Application類:
@SpringBootApplication
public class SsoClientApplication {
@Bean
public RequestContextListener requestContextListener() {
return new RequestContextListener();
} //自定義一個RequestContextListener
public static void main(String[] args) {
SpringApplication.run(SsoClientApplication.class, args);
}
}
接下來是Spring Security的配置檔案:
@EnableOAuth2Sso
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
}
下面是 WebMvcConfig:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
@Override
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
configurer.enable(); //使配置生效
}
/**
* 配置view
* @param registry
*/
@Override
public void addViewControllers(final ViewControllerRegistry registry) {
super.addViewControllers(registry);
registry.addViewController("/")
.setViewName("forward:/index");
registry.addViewController("/index");
registry.addViewController("/securedPage");
}
/**
* 對映資原始檔
* @param registry
*/
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**")
.addResourceLocations("/resources/");
}
}
application.yml檔案:
server:
port: 8989
session:
cookie:
name: UI2SESSION
security:
basic:
enabled: false
oauth2:
client:
clientId: SampleClientId #與server端對應
clientSecret: secret #與服務端對應
accessTokenUri: http://localhost:8080/auth/oauth/token
userAuthorizationUri: http://localhost:8080/auth/oauth/authorize
resource:
userInfoUri: http://localhost:8080/auth/door/me #資源伺服器,即對sso server的資源訪問。
spring:
thymeleaf:
cache: false
整體的架構也算搭好了,server端和client端都是用Spring Security,當用戶訪問client的頁面時,由Spring Security控制,會使其跳轉到sso Server端的預設login頁面進行驗證,也就是在Server端配置好的clientid,當驗證使用者名稱密碼通過時,返回給給客戶端,此時客戶端從security.oauth2.resource.userInfoUri的資源伺服器下獲取相應的資源。