OAuth 2.0 入门指南:掌握授权码模式

2023-12-25 09:28:33

一、授权码模式

???(1)spring-security-oauth2 从2.4.x版本开始,@EnableAuthorizationServer注解就弃用过时了?

? ?(2)当前演示Demo版本:springboot的1.5.x版本与spring-security-oauth2的2.3.8.RELEASE整合,如果使用springboot 2.x.x版本是不兼容的,程序会报错。

? ?(3)spring-security-oauth2 的2.3.8.RELEASE之后的版本与springboot 2.x.x的版本整合写法待学习。

二、所有关键代码参见👇

1、用户实体类 UserInfo

/**
 * 用户信息实体
 * @Author fenglm
 */
@Data
public class UserInfo {
    private String name;
    private String email;
}

2、获取用户信息 UserController

/**
 * 用户信息Controller
 * @Author fenglm
 */
@Controller
public class UserController {
    /**
     * 获取用户信息(资源API)
     * @return
     */
    @RequestMapping("/api/userinfo")
    public ResponseEntity<UserInfo> getUserInfo() {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String email = user.getUsername()+"@fenglm.com";
        UserInfo userInfo = new UserInfo();
        userInfo.setName(user.getUsername());
        userInfo.setEmail(email);
        return ResponseEntity.ok(userInfo);
    }
}

3、授权服务器配置OAuth2AuthorizationServer

/**
 * 授权服务器配置
 * 说明:
 * (1)org.springframework.security.oauth从2.4.x版本开始,@EnableAuthorizationServer等注解就弃用过时了,当前Demo使用的是2.3.8.RELEASE版本
 * (2)springboot版本:1.5.x 与 security.oauth版本:2.3.8.RELEASE 相对应整合,使用springboot 2.x.x版本是不兼容的
 * (3)2.3.8.RELEASE之后的版本、springboot 2.x.x的版本整合写法待学习
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServer extends AuthorizationServerConfigurerAdapter {

    @Override
    public void configure(ClientDetailsServiceConfigurer clientDetailsServiceConfigurer) throws Exception {
        clientDetailsServiceConfigurer.inMemory()
                .withClient("clientapp")
                .secret("112233")
                //重定向地址
                .redirectUris("http://localhost:9001/callback")
                //授权类型
                .authorizedGrantTypes("authorization_code")
                //权限范围
                .scopes("read_userinfo", "read_contacts");
    }
}

4、资源服务器配置OAuth2ResourceServer

/**
 * 资源服务器配置
 */
@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/api/**");
    }
}

5、配置文件application.properties

# Spring Security Setting
security.user.name=fenglm
security.user.password=sy123

6、pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.fenglm.server</groupId>
    <artifactId>authcode-server</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <name>authcode-server</name>
    <description>基于授权码模式+Spring Security OAuth2的最简授权服务器</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.security.oauth/spring-security-oauth2 -->
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.3.8.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <version>5.6.2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

三、演示流程

第1步:获取授权码

??????注:链接地址里的client_id注意需要跟后台代码里写的一致?点击获取授权码-浏览器请求(注:state参数暂忽略)icon-default.png?t=N7T8https://link.zhihu.com/?target=http%3A//localhost%3A8080/oauth/authorize%3Fclient_id%3Dclientapp%26redirect_uri%3Dhttp%3A//localhost%3A9001/callback%26response_type%3Dcode%26scope%3Dread_userinfo

?获取授权码-浏览器响应:http://localhost:9001/callback?code=8uYpdo

第2步:获取访问令牌

(1)获取访问令牌-请求示例(postman)
curl -X POST --user clientapp:112233 http://localhost:8080/oauth/token -H
"content-type: application/x-www-form-urlencoded" -d
"code=8uYpdo&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalh
ost%3A9001%2Fcallback&scope=read_userinfo"
(2)获取访问令牌-响应示例(postman)
{
    "access_token": "36cded80-b6f5-43b7-bdfc-594788a24530",
    "token_type": "bearer",
    "expires_in": 43199,
    "scope": "read_userinfo"
}

第3步:调用API获取用户资源

(1)调用API-请求示例(postman)
curl -X GET http://localhost:8080/api/userinfo -H "authorization: Bearer 36cded80-b6f5-43b7-bdfc-594788a24530"
(2)调用API-响应示例(postman)
{
    "name": "fenglm",
    "email": "fenglm@fenglm.com"
}

?想要了解更多实用小干货

可关注我的【知乎】?

文章来源:https://blog.csdn.net/Flemming323/article/details/135140789
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。