1 springboot的 springboot security OAuth的sso單點登入:
- 整個工程包括三個獨立的應用,一個認證服務和兩個客戶端應用,結構非常簡單。
Maven依賴
<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>
安全配置
客戶端的安全配置如下:
@Configuration
@EnableOAuth2Sso
public class UiSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers("/", "/login**")
.permitAll()
.anyRequest()
.authenticated();
}
}
配置最核心的部分是 @EnableOAuth2Sso註解來開啟SSO。這裡要注意,我們需要重寫WebSecurityConfigurerAdapter 否則所有的路徑都會受到SSO的保護,這樣無論使用者訪問哪個頁面都會被重定向到登入頁面,在這個例子裡,index和login頁面是唯一不需要被防護的。
最後,我們定義一個RequestContextListener bean來處理request scopes。
application.yml:
server:
port: 8082
context-path: /ui
session:
cookie:
name: UISESSION
security:
basic:
enabled: false
oauth2:
client:
clientId: SampleClientId
clientSecret: secret
accessTokenUri: http://localhost:8081/auth/oauth/token
userAuthorizationUri: http://localhost:8081/auth/oauth/authorize
resource:
userInfoUri: http://localhost:8081/auth/user/me
spring:
thymeleaf:
cache: false
說明:
我們禁用了default Basic Authentication
accessTokenUri 是獲取訪問令牌的URL
userAuthorizationUri是授權使用者被重定向的目標URL
userInfoUri是使用者終端訪問使用者資訊的URL
在這個case裡,認證服務是我們自己建設的,但是在實際的應用場景下認證服務往往是第三方提供的比如Facebook 或者 gitHub
前端
前端並非本文的重點,這裡簡單提一下。客戶端有一個非常簡單的前端頁面
index.html:
<h1>Spring Security SSO</h1>
<a href="securedPage">Login</a>
securedPage.html:
<h1>Secured Page</h1>
Welcome, <span th:text="${#authentication.name}">Name</span>
securedPage.html需要使用者通過授權才能訪問,如果一個未授權的使用者訪問這個頁面,他會被重定向到login頁面
3. 認證伺服器
3.1 Maven依賴
<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>
3.2 OAuth配置
本例中我們把AS(認證服務)器和RS放(資源伺服器)在一個例項中部署。
RS配置如下:
@EnableResourceServer
public class AuthorizationServerApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(AuthorizationServerApplication.class, args);
}
}
AS配置如下:
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private AuthenticationManager authenticationManager;
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
oauthServer.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()");
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory()
.withClient("SampleClientId")
.secret("secret")
.authorizedGrantTypes("authorization_code")
.scopes("user_info")
.autoApprove(true) ;
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager);
}
}
這裡我們只開啟authorization_code授權模式,另外這裡注意到autoApprove=true,這意味著使用者不會被重定向到授權的頁面,也不需要手動給請求授權。
3.3 安全配置
這裡需要定義一個簡單的認證機制
@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 {
auth.parentAuthenticationManager(authenticationManager)
.inMemoryAuthentication()
.withUser("john").password("123").roles("USER");
}
}
注意,我們用了in-memory認證,這裡只是做一個簡單的例子,我們直接把賬號密碼寫到記憶體裡了,真正使用的時候這裡要換成自定義的userDetailsService.
3.4 使用者終端
一個很簡單的返回JSON訊息的介面
@RestController
public class UserController {
@GetMapping("/user/me")
public Principal user(Principal principal) {
return principal;
}
}
完整的程式碼下載連結:Over On Github
作者:半夜菊花茶
連結:https://www.jianshu.com/p/d94bb118aa43
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。