springsecurity Oauth2.0 + jwt 极简入门demo

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、认证服务端搭建demo
    • 1. AuthorizationServerConfig Oauth2配置类
    • 2. JwtTokenConfig JWT配置类
    • 3. WebSecurityConfig springsecurity配置类
  • 二、四种认证模式
    • 1. 密码模式 password
    • 2. 客户端模式 client_credentials
    • 3. 简化模式 Implicit
    • 4. 授权码模式 authorization_code
  • 三、自定义授权客户端demo
    • 1. client配置
    • 2. WebSecurityConfig springsecurity配置类
    • 3. controller
    • 4.测试
  • 总结


前言

本章节是帮助我们快速上手使用 Spring 提供的 Spring Security OAuth2 搭建一套验证授权及资源访问服务,帮助大家实现企业微服务架构时能够有效的控制多个服务的统一登录、授权及资源保护工作。
server-gitee:https://gitee.com/golden-Kingdragon/springsecurity-oauth2-server-demo.git
client-gitee:https://gitee.com/golden-Kingdragon/springsecurity-oauth2-client-demo.git


提示:以下是本篇文章正文内容,下面案例可供参考

一、认证服务端搭建demo

先引入maven依赖

	<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-securityartifactId>
			<version>2.3.12.RELEASEversion>
		dependency>

		<dependency>
			<groupId>org.springframework.security.oauthgroupId>
			<artifactId>spring-security-oauth2artifactId>
			<version>2.3.4.RELEASEversion>
		dependency>
		<dependency>
			<groupId>org.springframework.securitygroupId>
			<artifactId>spring-security-jwtartifactId>
			<version>1.0.9.RELEASEversion>
		dependency>

1. AuthorizationServerConfig Oauth2配置类

package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
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.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import java.util.Arrays;


@Configuration
@EnableAuthorizationServer// 这个注解告诉 Spring 这个应用是 OAuth2 的授权服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

//    @Autowired
//    private JwtTokenConfig.CustomJwtTokenEnhancer customJwtTokenEnhancer;

    @Autowired
    private AuthorizationCodeServices authorizationCodeServices;
    //jwt配置
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;

    @Autowired
    private TokenStore tokenStore;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients()
                .tokenKeyAccess("permitAll()")
        .checkTokenAccess("permitAll()");//表单认证(申请令牌)
        ;

    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        //使用内存存储client凭证,可根据情况改用jdbc存储
        clients.inMemory()
                .withClient("along")
                .secret(passwordEncoder.encode("code"))
                .authorizedGrantTypes("authorization_code","client_credentials","password","implicit","refresh_token")
                .scopes("all")
                .redirectUris("http://127.0.0.1:8081/code")
                .accessTokenValiditySeconds(7200);
    }

    //jwtTokenStore存储
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager)
                .userDetailsService(userDetailsService)
        .authorizationCodeServices(authorizationCodeServices);
        //将增强的token设置到增强链中
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
//        enhancerChain.setTokenEnhancers(Arrays.asList(customJwtTokenEnhancer, jwtAccessTokenConverter));//添加额外信息
        enhancerChain.setTokenEnhancers(Arrays.asList(jwtAccessTokenConverter));

        endpoints.tokenStore(tokenStore)
                .accessTokenConverter(jwtAccessTokenConverter)
                .tokenEnhancer(enhancerChain);
    }



}

2. JwtTokenConfig JWT配置类

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
public class JwtTokenConfig {

//    @Component("customJwtTokenEnhancer")
//    public class CustomJwtTokenEnhancer implements TokenEnhancer {

        //实现TokenEhancer(令牌增强器)中的 ehance方法,增加额外的信息
//        @Override
//        public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
//            //token增强逻辑,务必确保保存的信息基本不变
//            Map additionalInfo = new HashMap<>();
//            //可以获取到代表当前用户的信息
//            Object userAuthentication = authentication.getPrincipal();
//            additionalInfo.put("Info", "value");
            Object userAuthentication = authentication.getPrincipal();

//            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);
//            return accessToken;
//        }
//    }

    @Bean
    public TokenStore tokenStore(){
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey("alongcode");
        return jwtAccessTokenConverter;
    }

}

3. WebSecurityConfig springsecurity配置类

package com.example.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
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.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public AuthorizationCodeServices authorizationCodeServices(){
        return new InMemoryAuthorizationCodeServices();
    }

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    // 设置添加用户信息,正常应该从数据库中读取
    @Bean
  public   UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
        userDetailsService.createUser(User.withUsername("user1")
                .password(passwordEncoder().encode("123456"))
                .authorities("ROLE_USER1").build());
        userDetailsService.createUser(User.withUsername("user2")
                .password(passwordEncoder().encode("123456"))
                .authorities("ROLE_USER2").build());
        return userDetailsService;
    }


        @Override
    protected void configure(HttpSecurity http) throws Exception {

            http.authorizeRequests()
                    .antMatchers("/oauth/**","/login/**","/logout/**")
                    .permitAll()
                    .anyRequest()
                    .authenticated()
                    .and()
                    .formLogin()
                    .permitAll()
                    .and()
                    .csrf()
                    .disable();

    }

}

二、四种认证模式

1. 密码模式 password

springsecurity Oauth2.0 + jwt 极简入门demo_第1张图片

2. 客户端模式 client_credentials

springsecurity Oauth2.0 + jwt 极简入门demo_第2张图片

3. 简化模式 Implicit

http://127.0.0.1:8080/oauth/authorize?response_type=token&client_id=along&redirect_uri=http://127.0.0.1:8081/code&scope=all

在这里插入图片描述
登录授权
springsecurity Oauth2.0 + jwt 极简入门demo_第3张图片
授权之后返回token
在这里插入图片描述

4. 授权码模式 authorization_code

http://127.0.0.1:8080/oauth/authorize?response_type=code&client_id=along&scope=all&redirect_uri=http://127.0.0.1:8081/code

在这里插入图片描述
同意授权
springsecurity Oauth2.0 + jwt 极简入门demo_第4张图片

在这里插入图片描述
获取token
springsecurity Oauth2.0 + jwt 极简入门demo_第5张图片

三、自定义授权客户端demo

先引入maven依赖

	<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-oauth2-clientartifactId>
			  <version>2.6.10version>
		dependency>
		<dependency>
			<groupId>org.springframework.bootgroupId>
			<artifactId>spring-boot-starter-webartifactId>
		dependency>

1. client配置

server:
  port: 8081
spring:
  security:
    oauth2:
      client:
        registration:
          alongcode:
            client-id: along
            client-secret: code
            authorization-grant-type: authorization_code
            redirect-uri: 'http://127.0.0.1:8081/code'
            client-name: alongcode
          github:
            client-id: asfasfasgw312d
            client-secret: afasfsafasfasfafasf
        provider:
          alongcode:
            authorization-uri: http://localhost:8080/oauth/authorize
            token-uri: http://localhost:8080/oauth/token


2. WebSecurityConfig springsecurity配置类

package com.example.demo.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests(a -> a
                        .antMatchers("/code/**", "/login", "/error", "/webjars/**").permitAll()
                        .anyRequest().authenticated()
                )
                .oauth2Login();
    }
}

3. controller

package com.example.demo.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.security.Principal;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(Principal principal) {
//        return "Hello," + principal.getName();
        return "Hello,aa";
    }

    @GetMapping("/code")
    public ResponseEntity<String> code(String code) {
//        return "Hello," + principal.getName();
        System.out.println(code);
        RestTemplate restTemplate = new RestTemplate();
        String access_token_url = "http://localhost:8080/oauth/token";

        MultiValueMap<String, Object> hashMap = new LinkedMultiValueMap<>();
        hashMap.add("grant_type","authorization_code");
        hashMap.add("code",code);
        hashMap.add("client_id","along");
        hashMap.add("client_secret","code");
        hashMap.add("redirect_uri","http://127.0.0.1:8081/code");

        ResponseEntity<String> responseEntity = restTemplate.postForEntity(access_token_url, hashMap, String.class);
        return responseEntity;
    }

}

4.测试

启动认证服务器和客户端
浏览器访问:http://localhost:8081/hello
springsecurity Oauth2.0 + jwt 极简入门demo_第6张图片

登录
springsecurity Oauth2.0 + jwt 极简入门demo_第7张图片
同意授权
springsecurity Oauth2.0 + jwt 极简入门demo_第8张图片
得到token
在这里插入图片描述
拿到token之后就可以完成自己的逻辑


总结

没有总结。

你可能感兴趣的:(服务器,spring,boot,java)