¿Es difícil dominar el inicio de sesión único de oauth2? solo configuralo

El inicio de sesión único es un requisito muy común en los sistemas distribuidos.

El sistema distribuido se compone de muchos subsistemas diferentes, y cuando usamos el sistema, solo necesitamos iniciar sesión una vez, por lo que otros sistemas piensan que el usuario ya ha iniciado sesión y no es necesario iniciar sesión nuevamente. Puede iniciar sesión en Taobao Tmall, Alipay, Alibaba Cloud y otros sitios web para experimentar el inicio de sesión único

Familiarizado con la función de inicio de sesión único de oauth2, Liu Bei se encontrará con Zhuge Liang cuando vaya a la entrevista, como pez en el agua.

Hoy, el hermano Heng quiere hablarle sobre Spring Boot+OAuth2 para el inicio de sesión único y usar la anotación @EnableOAuth2Sso para realizar rápidamente la función de inicio de sesión único.
Dirección de descarga del código fuente

Sin más preámbulos, comencemos con los pasos.

creación de proyectos

Cree el servidor de autorización y el servidor de recursos juntos (por supuesto, es mejor separarlos, pero también hay muchos productos empresariales que también se combinan, el propósito de esto es la conveniencia).

Hoy necesitamos un total de tres servicios:

Descripción del puerto del proyecto
servidor de autorización 9090 servidor de autorización + servidor de recursos
cliente1 9091 subsistema 1
cliente2 9092 subsistema 2
servidor de autenticación se utiliza para desempeñar el papel de servidor de autorización + servidor de recursos, cliente1 y cliente2 desempeñan el papel de subsistema respectivamente, y cliente1 esperará en el futuro Después de que el inicio de sesión sea exitoso, también podemos acceder al cliente2, para que podamos ver el efecto del inicio de sesión único.

Creamos un proyecto Maven llamado oauth2-sso como proyecto principal.

Centro de Certificación Unificado

A continuación, construyamos un centro de autenticación unificado.

  • Primero, creamos un módulo llamado auth-server y agregamos las siguientes dependencias al crearlo:
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>
  • Una vez que el proyecto se haya creado correctamente, este módulo desempeñará el papel de servidor de autorización + servidor de recursos, por lo que primero agregamos la anotación @EnableResourceServer a la clase de inicio de este proyecto, lo que indica que se trata de un servidor de recursos:
@SpringBootApplication
@EnableResourceServer
public class AuthServerApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(AuthServerApplication.class, args);
    }

}
  • A continuación, configuramos el servidor de autorizaciones. Dado que el servidor de recursos y el servidor de autorizaciones se fusionan, la configuración del servidor de autorizaciones es mucho más fácil:
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
    
    @Autowired
    PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
    
    
        security.checkTokenAccess("permitAll()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    
    
        clients.inMemory()
                .withClient("api")
                .secret(passwordEncoder.encode("123456"))
                .autoApprove(true)
                .redirectUris("http://127.0.0.1:9091/login", "http://127.0.0.1:9092/login")
                .scopes("user")
                .accessTokenValiditySeconds(7200)
                .authorizedGrantTypes("authorization_code");

    }
}

Aquí solo necesitas simplemente configurar la información del cliente, la configuración es muy sencilla

Por simplicidad, la configuración de la información del cliente se basa en la memoria

  • A continuación, configuremos Spring Security nuevamente:
@Configuration
@Order(1)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Bean
    PasswordEncoder passwordEncoder() {
    
    
        return new BCryptPasswordEncoder();
    }
    @Override
    public void configure(WebSecurity web) throws Exception {
    
    
        web.ignoring().antMatchers("/login.html", "/css/**", "/js/**", "/images/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.requestMatchers()
                .antMatchers("/login")
                .antMatchers("/oauth/authorize")
                .and()
                .authorizeRequests().anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html")
                .loginProcessingUrl("/login")
                .permitAll()
                .and()
                .csrf().disable();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    
    
        auth.inMemoryAuthentication()
                .withUser("harry")
                .password(passwordEncoder().encode("admin123"))
                .roles("admin");
    }
}

Aquí hay una descripción general aproximada:

1. Primero proporcione una instancia de BCryptPasswordEncoder para el cifrado y descifrado de contraseñas.
Dado que personalicé la página de inicio de sesión, estos recursos estáticos están permitidos en WebSecurity.
En HttpSecurity, liberamos puntos finales relacionados con la autenticación y configuramos la página de inicio de sesión y la interfaz de inicio de sesión al mismo tiempo.
2. Se proporciona un usuario basado en memoria en AuthenticationManagerBuilder (se puede modificar aquí para cargar desde la base de datos).
3. Hay otro punto clave, porque el servidor de recursos y el servidor de autorizaciones están juntos, por lo que necesitamos una anotación @Order para aumentar la prioridad de la configuración de Spring Security.

  • SecurityConfig y AuthServerConfig son cosas que el servidor de autorizaciones debe proporcionar. Si queremos dividir el servidor de autorizaciones y el servidor de recursos, también debemos proporcionar una interfaz que exponga la información del usuario (si el servidor de autorizaciones y el servidor de recursos están separados, esta interfaz será proporcionada por el servidor de recursos):
@RestController
public class UserController {
    
    
    @GetMapping("/user")
    public Principal getCurrentUser(Principal principal) {
    
    
        return principal;
    }
}
  • Finalmente, configuramos el puerto del proyecto en application.properties:

server.port=9091
Además, el hermano Heng preparó una página de inicio de sesión de antemano, de la siguiente manera:

inserte la descripción de la imagen aquí

  • Copie el html, css, js, etc. relacionado con la página de inicio de sesión en el directorio resources/static:
    inserte la descripción de la imagen aquí

  • Esta página es muy simple, solo un formulario de inicio de sesión, enumero las partes principales:

<form action="/login" method="post">
    <div class="input">
        <label for="name">用户名</label>
        <input type="text" name="username" id="name">
        <span class="spin"></span>
    </div>
    <div class="input">
        <label for="pass">密码</label>
        <input type="password" name="password" id="pass">
        <span class="spin"></span>
    </div>
    <div class="button login">
        <button type="submit">
            <span>登录</span>
            <i class="fa fa-check"></i>
        </button>
    </div>
</form>

Tenga en cuenta que la dirección de envío de la acción no debe ser incorrecta.

Después de eso, nuestra plataforma de inicio de sesión de autenticación unificada está bien.

creación de clientes

A continuación, creemos un proyecto de cliente, cree un proyecto Spring Boot llamado client1,

  • Agregue las siguientes dependencias:
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
        </dependency>

  • Después de que el proyecto se haya creado con éxito, configuremos Spring Security:
@Configuration
@EnableOAuth2Sso
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
    
    
        http.authorizeRequests().anyRequest().authenticated().and().csrf().disable();
    }
}

Esta configuración es muy simple, es decir, todas las interfaces de nuestro cliente1 deben estar autenticadas antes de poder acceder a ellas, y se agrega una anotación @EnableOAuth2Sso para habilitar la función de inicio de sesión único.

  • A continuación, proporcionaremos otra interfaz de prueba en client1:
@RestController
public class UserController {
    
    
    @Value("${server.port}")
    private String port;
    @GetMapping("/getLogin")
    public String getLogin() {
    
    

        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return "当前登录的用户是"+authentication.getName() + Arrays.toString(authentication.getAuthorities().toArray())+",登录端口:"+port;
    }
}

Esta interfaz de prueba devuelve el nombre y la información de la función del usuario conectado actualmente y el número de puerto de servicio.

  • A continuación, debemos configurar la información relacionada con oauth2 en application.properties de client1:
security.oauth2.client.client-secret=123456
security.oauth2.client.client-id=api
security.oauth2.client.user-authorization-uri=http://127.0.0.1:9090/oauth/authorize
security.oauth2.client.access-token-uri=http://127.0.0.1:9090/oauth/token
security.oauth2.resource.user-info-uri=http://127.0.0.1:9090/user

server.port=9091

server.servlet.session.cookie.name=client1

La configuración aquí también es familiar, echemos un vistazo:

client-secret es el secreto del cliente.
client-id es la identificación del cliente.
user-authorization-uri es el punto final para la autorización del usuario.
access-token-uri es el punto final para obtener el token.
user-info-uri es la interfaz para obtener información del usuario (obtenida del servidor de recursos).
Finalmente, configure el puerto y asigne un nombre a la cookie.
Después de eso, la configuración de nuestro cliente1 está completa.

De la misma manera, vamos a configurar otro cliente 2. El Cliente 2 es exactamente igual que el cliente 1, excepto que el nombre de la cookie es diferente (puede elegirlo a voluntad, pero puede ser diferente).

prueba

A continuación, iniciamos auth-server, client1 y client2 respectivamente. Primero, intentamos ir a la interfaz getLogin en client1. En este momento, saltará automáticamente al centro de autenticación unificado
e ingresará el nombre de usuario: harry, la contraseña: admin123.

Después de un inicio de sesión exitoso, volverá automáticamente a la interfaz de saludo del cliente1, de la siguiente manera:

inserte la descripción de la imagen aquí

Después de que el cliente1 inicie sesión, vamos a visitar al cliente2 nuevamente y encontramos que no es necesario iniciar sesión, y podemos acceder directamente a:
inserte la descripción de la imagen aquí

OK, después de eso, nuestro inicio de sesión único es exitoso.

Análisis de proceso

Finalmente, permítanme repasar un proceso de ejecución del código anterior con mis amigos:

1. En primer lugar, vamos a acceder a la interfaz /getLogin del cliente1, que requiere iniciar sesión para acceder, por lo que nuestra solicitud es interceptada, luego de la interceptación, el sistema nos redirigirá a la interfaz /login del cliente1, que nos permite Ir a iniciar sesión .

inserte la descripción de la imagen aquí

2. Cuando accedamos a la interfaz de inicio de sesión del cliente1, ya que hemos configurado la anotación @EnableOAuth2Sso, esta operación será interceptada nuevamente y el interceptor de inicio de sesión único iniciará automáticamente una solicitud para obtener autorización de acuerdo con nuestra configuración en application.properties código:

inserte la descripción de la imagen aquí

3. La solicitud enviada en el segundo paso es solicitar algo en el servicio del servidor de autenticación. Por supuesto, esta solicitud no puede evitar la necesidad de iniciar sesión primero, por lo que se redirige a la página de inicio de sesión del servidor de autenticación nuevamente, que es el centro de autenticación unificado que ves.
inserte la descripción de la imagen aquí

4. Después de que el centro de autenticación unificado complete la función de inicio de sesión, continuará ejecutando el segundo paso de la solicitud, y en este momento se puede obtener con éxito el código de autorización.
inserte la descripción de la imagen aquí
inserte la descripción de la imagen aquí

5. Después de obtener el código de autorización, será redirigido a la página de inicio de sesión de nuestro cliente1 en este momento, pero de hecho nuestro cliente1 no tiene una página de inicio de sesión, por lo que esta operación aún será interceptada y la dirección interceptada en este momento contiene el código de autorización, tome el código de autorización e inicie una solicitud al servidor de autenticación en la clase OAuth2ClientAuthenticationProcessingFilter, y puede obtener access_token.
inserte la descripción de la imagen aquí

6. Después de obtener el token de acceso en el quinto paso, envíe una solicitud a la dirección uri de información de usuario que configuramos para obtener la información de usuario de inicio de sesión. Después de obtener la información de usuario, vuelva a realizar el proceso de inicio de sesión de Spring Security en el cliente 1. Está bien .

Aquellos que necesiten aprender el proyecto pueden ir a mi github para clonar
la dirección del código fuente de GitHub

Supongo que te gusta

Origin blog.csdn.net/huangxuanheng/article/details/119052844
Recomendado
Clasificación