0
点赞
收藏
分享

微信扫一扫

三. 单点登录示例

一 . 概述

1.1 认证服务器

依赖

<dependencies>
    <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>
        <version>2.3.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth.boot</groupId>
        <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        <version>2.1.9.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
</dependencies>

Yml配置

server:
  port: 7070

  servlet:
    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;
    }
}

登录页面

<body>
    <h1>用户登录</h1>
    <form action="authentication/form" method="post">
        username: <input name="username"/><br>
        Password: <input name="password"/><br>
        <button>提交</button>
    </form>
</body>

1.2 子系统client-a

依赖

<dependencies>
    <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>
        <version>2.3.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security.oauth.boot</groupId>
        <artifactId>spring-security-oauth2-autoconfigure</artifactId>
        <version>2.1.9.RELEASE</version>
    </dependency>
</dependencies>

配置

server:
  port: 8081
  servlet:
    context-path: /clientA

security:
  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/authorize

    resource:
      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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <H1>应用AAAA</H1>
    <a href="http://localhost:8082/clientB">访问B服务</a>
</body>
</html>

1.2 子系统client-b

依赖

        <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>
            <version>2.3.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.1.9.RELEASE</version>
        </dependency>

yml配置

server:
  port: 8082
  servlet:
    context-path: /clientB

security:
  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/authorize

    resource:
      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

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <H1>应用B</H1>
    <a href="http://localhost:8081/clientA">访问A服务</a>
</body>
</html>
举报

相关推荐

0 条评论