一、依赖
<dependency>
<groupId>org.springframework.security.oauth.boot</groupId>
<artifactId>spring-security-oauth2-autoconfigure</artifactId>
<version>2.1.6.RELEASE</version>
</dependency>
二、服务端
1.服务端需要的是授权与身份验证,通过配置@EnableAuthorizationServer、@EnableWebSecurity、@EnableResourceServer来完成配置。
2.先来配置WebSecurity的配置
package com.example.oauth;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
* @author sorata
* @date 2019-07-23 09:19
*/
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.BASIC_AUTH_ORDER)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService myUserDetailsService(){
return new InMemoryUserDetailsManager(User.builder().username("admin").password(passwordEncoder().encode("admin")).roles("ADMIN").build());
}
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myUserDetailsService()).passwordEncoder(passwordEncoder());
}
@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/**")
.authorizeRequests()
.antMatchers("/","/login","/oauth/**").permitAll()
.anyRequest().authenticated()
.and().httpBasic().and().formLogin()
.and().logout();
}
}
note:首先是配置用户UserDetailsService,然后配置密码策略。主要的部分是 configure(HttpSecurity http) 方法,这里当我在formLogin()后配置了验证完成转发,即successForwardUrl(“/main”)后,sso客户端请求验证完成时,不会跳转到客户端的请求地址,而是跳转到验证成功的服务端地址 /main。
3.编写一个用户信息的controller
package com.example.oauth;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
/**
* @author sorata
* @date 2019-07-23 09:17
*/
@RestController
public class UserController {
@RequestMapping("/user")
public Principal principal(Principal principal){
return principal;
}
@RequestMapping("/user2")
public Principal principal2(Principal principal){
return principal;
}
}
note: 作用就是测试和之后客户端填写的服务器用户信息的url
4.资源服务器
package com.example.oauth;
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;
/**
* @author sorata
* @date 2019-07-23 09:50
*/
@Configuration
@EnableResourceServer
public class ResourceConfig extends ResourceServerConfigurerAdapter {
@Override
public void configure(HttpSecurity http) throws Exception {
http.csrf().disable().antMatcher("/user")
.authorizeRequests().anyRequest().authenticated();
}
}
5.完成后的效果
6. 重要的认证服务端
package com.example.oauth;
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.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
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.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
/**
* @author sorata
* @date 2019-07-23 10:06
*/
@Configuration
@EnableAuthorizationServer
public class SsoServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired private AuthenticationManager authenticationManager;
@Autowired private BCryptPasswordEncoder passwordEncoder;
/**
* 如果出现错误 在主类上去掉默认配置
* {@link SsoServerApplication}
*/
@Autowired private UserDetailsService detailsService;
@Override
public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
security.allowFormAuthenticationForClients()
.tokenKeyAccess("permitAll()")
.checkTokenAccess("isAuthenticated()")
.passwordEncoder(passwordEncoder);
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients.inMemory().withClient("cocos")
.secret(passwordEncoder.encode("cocos"))
.autoApprove(true)
.redirectUris("http://localhost:9090/client/login")
.scopes("all")
.authorities("ADMIN")
.authorizedGrantTypes("authorization_code","password","refresh_token")
.accessTokenValiditySeconds(10000)
.refreshTokenValiditySeconds(10000);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager(authenticationManager)
.userDetailsService(detailsService).tokenStore(tokenStore());
}
@Bean
public TokenStore tokenStore(){
return new InMemoryTokenStore();
}
}
三、客户端
1.客户端实现比较简单,如果想针对行的修改,自定义那么可以根据后面参考地址研读。
2.application.properties
security.oauth2.client.authentication-scheme=form
security.oauth2.client.user-authorization-uri=http://localhost:8080/server/oauth/authorize
security.oauth2.client.access-token-uri=http://localhost:8080/server/oauth/token
security.oauth2.client.client-id=cocos
security.oauth2.client.client-secret=cocos
security.oauth2.resource.user-info-uri=http://localhost:8080/server/user
server.servlet.context-path=/client
server.port=9090
3.主类添加注解
package com.example.oauth;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
@SpringBootApplication
@EnableOAuth2Sso
public class SsoClientApplication {
public static void main(String[] args) {
SpringApplication.run(SsoClientApplication.class, args);
}
}
4.用户的接口
package com.example.oauth;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.Principal;
/**
* @author sorata
* @date 2019-07-23 10:30
*/
@RestController
public class UserController {
@RequestMapping("/user")
public Principal principal(Principal principal){
return principal;
}
}
四、效果
note: 如果想看到
1. oauth2 地址:https://tools.ietf.org/html/rfc6749
2. 项目源码:https://gitee.com/swiftloop/sso-simple-demo
3. 参考:https://spring.io/guides/tutorials/spring-boot-oauth2/
来源:oschina
链接:https://my.oschina.net/u/2661827/blog/3077724