三.|三. 单点登录示例

一 . 概述

单点登录(Singal Sign On)是很多企业经常使用的一种登录方式,那么何为单点登录呢?为了解决什么样的问题呢?举个例子,在淘宝公司内部,有天猫、淘宝、阿里云、聚划算等众多的产品线,这些产品线是不同的服务器来支撑运行,但是作为用户的我们却可以使用同一套账户名和密码进行登录他几乎所有的产品,登录服务器只有一个,根据登录服务器返回的特定的信息,可以去访问它所有的产品线。着就是所谓的单点登录。
1.1 认证服务器
  • 三.|三. 单点登录示例
    文章图片
【三.|三. 单点登录示例】依赖
org.springframework.boot spring-boot-starter-web org.springframework.security.oauth spring-security-oauth2 2.3.6.RELEASE org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.1.9.RELEASE org.slf4j slf4j-api

Yml配置
server: port: 7070servlet: context-path: /auth

授权服务
@EnableAuthorizationServer @Configuration public class JwtServerConfig extends AuthorizationServerConfigurerAdapter { @Autowired private PasswordEncoder passwordEncoder; // jwt的生成器 @Bean public JwtAccessTokenConverter jwtAccessTokenConverter() { JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter(); jwtAccessTokenConverter.setSigningKey("abcxyz"); return jwtAccessTokenConverter; } @Override public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { endpoints.accessTokenConverter(jwtAccessTokenConverter())//配置JWT的生成器 .allowedTokenEndpointRequestMethods(HttpMethod.POST, HttpMethod.GET); } // 客户端的配置 @Override public void configure(ClientDetailsServiceConfigurer clients) throws Exception { clients.inMemory()// .withClient("client-a") // client_id .secret("$2a$10$GqJuJhe7zmtwwThIed7smu9zMJBgSQzFMP47eEDL.g9tg8Y82.A7m") // client_secret .authorizedGrantTypes("authorization_code")//采用什么方式获取access_token .redirectUris("http://localhost:8081/clientA/login") .scopes("all") .autoApprove(true) //自动授权 .and() .withClient("client-b") // client_id .secret("$2a$10$GqJuJhe7zmtwwThIed7smu9zMJBgSQzFMP47eEDL.g9tg8Y82.A7m") // client_secret .authorizedGrantTypes("authorization_code")//采用什么方式获取access_token .redirectUris("http://localhost:8082/clientB/login") .scopes("all") .autoApprove(true); } @Override public void configure(AuthorizationServerSecurityConfigurer security) throws Exception { security.allowFormAuthenticationForClients() .checkTokenAccess("isAuthenticated()") .passwordEncoder(passwordEncoder); } }

安全配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @Configuration public class WebSecurityConfig extends WebSecurityConfigurerAdapter { /** * 该bean的作用是,在UserDetailsService接口的loadUserByUsername返回的UserDetail中包含了 * password, 该bean就将用户从页面提交过来的密码进行处理,处理之后与UserDetail中密码进行比较。 * @return */ @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } // 统一安全配置 @Override protected void configure(HttpSecurity http) throws Exception {// 意思是将图片验证码过滤器,加载用户名密码验证过滤器之前 http.formLogin()//使用form进行登录 .loginPage("/login.html")//指定登录页面 .loginProcessingUrl("/authentication/form")//表示form往哪里进行提交 .and() .authorizeRequests() .antMatchers("/login.html", "/images/**").permitAll() .anyRequest() .authenticated() .and() .csrf().disable(); } // 密码加密处理 public static void main(String[] args) { BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder(); System.out.println(bCryptPasswordEncoder.encode("1")); } }

自定义认证
// 该类的作用是处理用户登录名和密码 @Component public class UserSecurityService implements UserDetailsService {@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = new User(username, "$2a$10$GqJuJhe7zmtwwThIed7smu9zMJBgSQzFMP47eEDL.g9tg8Y82.A7m", Arrays.asList(new SimpleGrantedAuthority("ROLE_user"), new SimpleGrantedAuthority("ROLE_admin"))); return user; } }

登录页面
用户登录
username:
Password:

1.2 子系统client-a
  • 三.|三. 单点登录示例
    文章图片
依赖
org.springframework.boot spring-boot-starter-web org.springframework.security.oauth spring-security-oauth2 2.3.6.RELEASE org.springframework.boot spring-boot-starter-security org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.1.9.RELEASE

配置
server: port: 8081 servlet: context-path: /clientAsecurity: oauth2: client: client-id: client-a client-secret: 1 # 在每个服务器中要保存 access_token access-token-uri: http://localhost:7070/auth/oauth/token user-authorization-uri: http://localhost:7070/auth/oauth/authorizeresource: jwt: key-value: abcxyz#验签

启动类配置
@SpringBootApplication @EnableOAuth2Sso // 启动权限认证 @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled=true) public class SsoClientApplicationA { public static void main(String[] args) { SpringApplication.run(SsoClientApplicationA.class, args); } }

controller示例
@RequestMapping @RestController public class UserController { @RequestMapping("/user") @PreAuthorize("hasAuthority('ROLE_admin')") public Object get(Authentication authentication) { System.out.println("ClientA: " + authentication.getName() + "; ; " + authentication.getAuthorities()); return "clientA"; } @RequestMapping("/login") @PreAuthorize("hasAuthority('ROLE_admin')") public Object hello(Authentication authentication) { System.out.println("ClientA: " + authentication.getName() + "; ; " + authentication.getAuthorities()); return "hello_A"; } }

index.html
Title - 锐客网 应用AAAA 访问B服务

1.2 子系统client-b
  • 三.|三. 单点登录示例
    文章图片
依赖
org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.security.oauth spring-security-oauth2 2.3.6.RELEASE org.springframework.security.oauth.boot spring-security-oauth2-autoconfigure 2.1.9.RELEASE

yml配置
server: port: 8082 servlet: context-path: /clientBsecurity: oauth2: client: client-id: client-b client-secret: 1 access-token-uri: http://localhost:7070/auth/oauth/token user-authorization-uri: http://localhost:7070/auth/oauth/authorizeresource: jwt: key-value: abcxyz#验签

启动类配置
@SpringBootApplication @EnableOAuth2Sso @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled=true) public class SsoClientApplicationB { public static void main(String[] args) { SpringApplication.run(SsoClientApplicationB.class, args); } }

controller示例
@RestController @RequestMapping public class UserController {@RequestMapping("/info") @RolesAllowed("ROLE_admin") public Object get(Authentication authentication) { System.out.println("ClientB: " + authentication.getName() + "; ; " + authentication.getAuthorities()); return "clientA"; } @RequestMapping @RolesAllowed("ROLE_admin") public Object hello(Authentication authentication) { System.out.println("ClientB: " + authentication.getName() + "; ; " + authentication.getAuthorities()); return "hello_B"; } }

index.html
Title - 锐客网 应用B 访问A服务

源码: 链接:https://pan.baidu.com/s/1hDeo-gMwuStKaL1mniUDog&shfl=sharepset 密码:t4s4

    推荐阅读