zoukankan      html  css  js  c++  java
  • Spring Security实现OAuth2.0授权服务

    Spring Security实现OAuth2.0授权服务 - 基础版》介绍了如何使用Spring Security实现OAuth2.0授权和资源保护,但是使用的都是Spring Security默认的登录页、授权页,client和token信息也是保存在内存中的。

    本文将介绍如何在Spring Security OAuth项目中自定义登录页面、自定义授权页面、数据库配置client信息、数据库保存授权码和token令牌。

    一、引入依赖

    需要在基础版之上引入thymeleaf、JDBC、mybatis、mysql等依赖。

     1 <!-- thymeleaf -->
     2 <dependency>
     3     <groupId>org.springframework.boot</groupId>
     4     <artifactId>spring-boot-starter-thymeleaf</artifactId>
     5 </dependency>
     6 <dependency>
     7     <groupId>org.thymeleaf.extras</groupId>
     8     <artifactId>thymeleaf-extras-springsecurity4</artifactId>
     9 </dependency>
    10 
    11 <!-- JDBC -->
    12 <dependency>
    13     <groupId>org.springframework.boot</groupId>
    14     <artifactId>spring-boot-starter-jdbc</artifactId>
    15 </dependency>
    16 <dependency>
    17     <groupId>org.apache.commons</groupId>
    18     <artifactId>commons-dbcp2</artifactId>
    19 </dependency>
    20 
    21 <!-- Mybatis -->
    22 <dependency>
    23     <groupId>org.mybatis.spring.boot</groupId>
    24     <artifactId>mybatis-spring-boot-starter</artifactId>
    25     <version>1.1.1</version>
    26 </dependency>
    27 
    28 <!-- MySQL -->
    29 <dependency>
    30     <groupId>mysql</groupId>
    31     <artifactId>mysql-connector-java</artifactId>
    32 </dependency>

    二、client和token表

     1 -- used in tests that use HSQL
     2 create table oauth_client_details (
     3   client_id VARCHAR(255) PRIMARY KEY,
     4   resource_ids VARCHAR(255),
     5   client_secret VARCHAR(255),
     6   scope VARCHAR(255),
     7   authorized_grant_types VARCHAR(255),
     8   web_server_redirect_uri VARCHAR(255),
     9   authorities VARCHAR(255),
    10   access_token_validity INTEGER,
    11   refresh_token_validity INTEGER,
    12   additional_information TEXT(4096),
    13   autoapprove VARCHAR(255)
    14 );
    15 
    16 create table oauth_client_token (
    17   token_id VARCHAR(255),
    18   token BLOB,
    19   authentication_id VARCHAR(255) PRIMARY KEY,
    20   user_name VARCHAR(255),
    21   client_id VARCHAR(255)
    22 );
    23 
    24 create table oauth_access_token (
    25   token_id VARCHAR(255),
    26   token BLOB,
    27   authentication_id VARCHAR(255) PRIMARY KEY,
    28   user_name VARCHAR(255),
    29   client_id VARCHAR(255),
    30   authentication BLOB,
    31   refresh_token VARCHAR(255)
    32 );
    33 
    34 create table oauth_refresh_token (
    35   token_id VARCHAR(255),
    36   token BLOB,
    37   authentication BLOB
    38 );
    39 
    40 create table oauth_code (
    41   code VARCHAR(255), authentication BLOB
    42 );
    43 
    44 create table oauth_approvals (
    45     userId VARCHAR(255),
    46     clientId VARCHAR(255),
    47     scope VARCHAR(255),
    48     status VARCHAR(10),
    49     expiresAt TIMESTAMP,
    50     lastModifiedAt TIMESTAMP
    51 );
    52 
    53 
    54 -- customized oauth_client_details table
    55 create table ClientDetails (
    56   appId VARCHAR(255) PRIMARY KEY,
    57   resourceIds VARCHAR(255),
    58   appSecret VARCHAR(255),
    59   scope VARCHAR(255),
    60   grantTypes VARCHAR(255),
    61   redirectUrl VARCHAR(255),
    62   authorities VARCHAR(255),
    63   access_token_validity INTEGER,
    64   refresh_token_validity INTEGER,
    65   additionalInformation VARCHAR(4096),
    66   autoApproveScopes VARCHAR(255)
    67 );
    View Code

    在oauth_client_details表添加数据:

    1 INSERT INTO `oauth_client_details` VALUES ('net5ijy', NULL, '123456', 'all,read,write', 'authorization_code,refresh_token,password', NULL, 'ROLE_TRUSTED_CLIENT', 7200, 7200, NULL, NULL);
    2 INSERT INTO `oauth_client_details` VALUES ('tencent', NULL, '123456', 'all,read,write', 'authorization_code,refresh_code', NULL, 'ROLE_TRUSTED_CLIENT', 3600, 3600, NULL, NULL);

    三、用户、角色表

     1 CREATE TABLE `springcloud_user` (
     2 `id`  int(11) NOT NULL AUTO_INCREMENT ,
     3 `username`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
     4 `password`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
     5 `phone`  varchar(11) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
     6 `email`  varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
     7 `create_time`  datetime NOT NULL ,
     8 PRIMARY KEY (`id`)
     9 )
    10 ENGINE=InnoDB
    11 DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    12 AUTO_INCREMENT=1;
    13 
    14 CREATE TABLE `springcloud_role` (
    15 `id`  int(11) NOT NULL AUTO_INCREMENT ,
    16 `name`  varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL ,
    17 PRIMARY KEY (`id`)
    18 )
    19 ENGINE=InnoDB
    20 DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
    21 AUTO_INCREMENT=1;
    22 
    23 CREATE TABLE `springcloud_user_role` (
    24 `user_id`  int(11) NOT NULL ,
    25 `role_id`  int(11) NOT NULL ,
    26 FOREIGN KEY (`role_id`) REFERENCES `springcloud_role` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
    27 FOREIGN KEY (`user_id`) REFERENCES `springcloud_user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
    28 INDEX `user_id_fk` USING BTREE (`user_id`) ,
    29 INDEX `role_id_fk` USING BTREE (`role_id`) 
    30 )
    31 ENGINE=InnoDB
    32 DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci;
    View Code

    用户表添加数据

    1 INSERT INTO `springcloud_user` VALUES (1, 'admin001', '$2a$10$sXHKvdufrEfE2900ME40nOSBmeHRRUOF71szu22uaqqL8FIJeJDYW', '13622114309', '13622114309@189.cn', '2019-4-7 09:31:07');
    2 INSERT INTO `springcloud_user` VALUES (2, 'admin002', '$2a$10$sXHKvdufrEfE2900ME40nOSBmeHRRUOF71szu22uaqqL8FIJeJDYW', '17809837654', '17809837654@189.cn', '2019-4-7 09:33:00');

    角色表添加数据

    1 INSERT INTO `springcloud_role` VALUES (1, 'ADMIN');
    2 INSERT INTO `springcloud_role` VALUES (2, 'DBA');
    3 INSERT INTO `springcloud_role` VALUES (3, 'USER');

    用户角色关系表添加数据

    1 INSERT INTO `springcloud_user_role` VALUES (1, 1);
    2 INSERT INTO `springcloud_user_role` VALUES (2, 1);

    四、实体类和工具类

    1、User实体类

    封装授权服务器登录用户信息

     1 public class User implements Serializable {
     2 
     3     private Integer id;
     4     private String username;
     5     private String password;
     6     private String phone;
     7     private String email;
     8     private Set<Role> roles = new HashSet<Role>();
     9     private Date createTime;
    10 
    11     // getter & setter
    12 
    13     @Override
    14     public int hashCode() {
    15         final int prime = 31;
    16         int result = 1;
    17         result = prime * result + ((id == null) ? 0 : id.hashCode());
    18         return result;
    19     }
    20     @Override
    21     public boolean equals(Object obj) {
    22         if (this == obj)
    23             return true;
    24         if (obj == null)
    25             return false;
    26         if (getClass() != obj.getClass())
    27             return false;
    28         User other = (User) obj;
    29         if (id == null) {
    30             if (other.id != null)
    31                 return false;
    32         } else if (!id.equals(other.id))
    33             return false;
    34         return true;
    35     }
    36     @Override
    37     public String toString() {
    38         return "User [id=" + id + ", username=" + username + ", password="
    39                 + password + ", phone=" + phone + ", email=" + email
    40                 + ", roles=" + roles + ", createTime=" + createTime + "]";
    41     }
    42 }
    View Code

    2、Role实体类

    封装角色信息

     1 public class Role implements Serializable {
     2 
     3     private Integer id;
     4     private String name;
     5 
     6     public Role() {
     7         super();
     8     }
     9     public Role(String name) {
    10         super();
    11         this.name = name;
    12     }
    13 
    14     // getter & setter
    15 
    16     @Override
    17     public String toString() {
    18         return "Role [id=" + id + ", name=" + name + "]";
    19     }
    20 }

    3、ResponseMessage工具类

    封装接口响应信息

     1 public class ResponseMessage {
     2 
     3     private Integer code;
     4     private String message;
     5 
     6     public ResponseMessage() {
     7         super();
     8     }
     9 
    10     public ResponseMessage(Integer code, String message) {
    11         super();
    12         this.code = code;
    13         this.message = message;
    14     }
    15 
    16     // getter & setter
    17 
    18     public static ResponseMessage success() {
    19         return new ResponseMessage(0, "操作成功");
    20     }
    21 
    22     public static ResponseMessage fail() {
    23         return new ResponseMessage(99, "操作失败");
    24     }
    25 }
    View Code

    五、DAO和Service编写

    1、数据源配置

    在application.properties文件配置datasource

     1 spring.datasource.url=jdbc:mysql://localhost:3306/test
     2 spring.datasource.username=system
     3 spring.datasource.password=123456
     4 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
     5 
     6 spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
     7 spring.datasource.dbcp2.initial-size=5
     8 spring.datasource.dbcp2.max-active=25
     9 spring.datasource.dbcp2.max-idle=10
    10 spring.datasource.dbcp2.min-idle=5
    11 spring.datasource.dbcp2.max-wait-millis=10000
    12 spring.datasource.dbcp2.validation-query=SELECT 1
    13 spring.datasource.dbcp2.connection-properties=characterEncoding=utf8

    使用dbcp2数据源

    2、mapper.xml

    在src/main/resources下创建org.net5ijy.oauth2.mapper包,创建user-mapper.xml配置文件

     1 <mapper namespace="org.net5ijy.oauth2.repository.UserRepository">
     2 
     3     <resultMap type="User" id="UserResultMap">
     4         <result column="id" property="id" jdbcType="INTEGER" javaType="int" />
     5         <result column="username" property="username" jdbcType="VARCHAR"
     6             javaType="string" />
     7         <result column="password" property="password" jdbcType="VARCHAR"
     8             javaType="string" />
     9         <result column="phone" property="phone" jdbcType="VARCHAR"
    10             javaType="string" />
    11         <result column="email" property="email" jdbcType="VARCHAR"
    12             javaType="string" />
    13         <result column="create_time" property="createTime" jdbcType="TIMESTAMP"
    14             javaType="java.util.Date" />
    15         <collection property="roles" select="selectRolesByUserId"
    16             column="id"></collection>
    17     </resultMap>
    18 
    19     <!-- 根据用户名查询用户 -->
    20     <select id="findByUsername" parameterType="java.lang.String"
    21         resultMap="UserResultMap">
    22         <![CDATA[
    23         select * from springcloud_user where username = #{username}
    24         ]]>
    25     </select>
    26 
    27     <!-- 根据user id查询用户拥有的role -->
    28     <select id="selectRolesByUserId" parameterType="java.lang.Integer"
    29         resultType="Role">
    30         <![CDATA[
    31         select r.id, r.name from springcloud_user_role ur, springcloud_role r
    32         where ur.role_id = r.id and ur.user_id = #{id}
    33         ]]>
    34     </select>
    35 
    36 </mapper>
    View Code

    因为我们的例子只使用了findByUsername功能,所以只写这个sql就可以了

    3、DAO接口

    1 public interface UserRepository {
    2 
    3     User findByUsername(String username);
    4 }

    4、UserService

    接口

    1 public interface UserService {
    2 
    3     User getUser(String username);
    4 }

    实现类

     1 @Service
     2 public class UserServiceImpl implements UserService {
     3 
     4     static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
     5 
     6     @Autowired
     7     private UserRepository userRepository;
     8 
     9     @Autowired
    10     private JdbcTemplate jdbcTemplate;
    11 
    12     @Override
    13     public User getUser(String username) {
    14         return userRepository.findByUsername(username);
    15     }
    16 }

    5、UserDetailsService实现类

    这个接口的实现类需要在Security中配置,Security会使用这个类根据用户名查询用户信息,然后进行用户名、密码的验证。主要就是实现loadUserByUsername方法:

     1 @Service
     2 public class UserDetailsServiceImpl implements UserDetailsService {
     3 
     4     @Autowired
     5     private UserService userService;
     6 
     7     @Override
     8     public UserDetails loadUserByUsername(String username)
     9             throws UsernameNotFoundException {
    10 
    11         User user = userService.getUser(username);
    12         if (user == null || user.getId() < 1) {
    13             throw new UsernameNotFoundException("Username not found: "
    14                     + username);
    15         }
    16 
    17         return new org.springframework.security.core.userdetails.User(
    18                 user.getUsername(), user.getPassword(), true, true, true, true,
    19                 getGrantedAuthorities(user));
    20     }
    21 
    22     private Collection<? extends GrantedAuthority> getGrantedAuthorities(
    23             User user) {
    24         Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
    25         for (Role role : user.getRoles()) {
    26             authorities
    27                     .add(new SimpleGrantedAuthority("ROLE_" + role.getName()));
    28         }
    29         return authorities;
    30     }
    31 }
    View Code

    六、自定义登录页面

    1、controller编写

    编写LoginController类,添加login方法

     1 @RestController
     2 public class LoginController {
     3 
     4     @GetMapping("/login")
     5     public ModelAndView login() {
     6         return new ModelAndView("login");
     7     }
     8 
     9     @GetMapping("/login-error")
    10     public ModelAndView loginError(HttpServletRequest request, Model model) {
    11         model.addAttribute("loginError", true);
    12         model.addAttribute("errorMsg", "登陆失败,账号或者密码错误!");
    13         return new ModelAndView("login", "userModel", model);
    14     }
    15 }

    2、页面代码

    页面代码使用到了thymeleaf、bootstrap、表单验证等,具体的js、css引入就不赘述了,只记录最主要的内容:

     1 <div>
     2     <form th:action="@{/login}" method="post">
     3         <div>
     4             <label>&ensp;&ensp;名: </label>
     5             <div>
     6                 <input name="username" />
     7             </div>
     8         </div>
     9         <div>
    10             <label>密&#12288;&#12288;码: </label>
    11             <div>
    12                 <input type="password" name="password" />
    13             </div>
    14         </div>
    15         <div>
    16             <div>
    17                 <button type="submit"> 登 陆 </button>
    18             </div>
    19         </div>
    20     </form>
    21 </div>

    七、自定义授权页面

    1、controller编写

    编写GrantController类,添加getAccessConfirmation方法

     1 @Controller
     2 @SessionAttributes("authorizationRequest")
     3 public class GrantController {
     4 
     5     @RequestMapping("/oauth/confirm_access")
     6     public ModelAndView getAccessConfirmation(Map<String, Object> model,
     7             HttpServletRequest request) throws Exception {
     8 
     9         AuthorizationRequest authorizationRequest = (AuthorizationRequest) model
    10                 .get("authorizationRequest");
    11 
    12         ModelAndView view = new ModelAndView("base-grant");
    13         view.addObject("clientId", authorizationRequest.getClientId());
    14 
    15         return view;
    16     }
    17 }

    此处获取到申请授权的clientid用于在页面展示

    2、页面代码

    此处只写最主要的部分

     1 <div>
     2     <div>
     3         <div>OAUTH-BOOT 授权</div>
     4         <div>
     5             <a href="javascript:;">帮助</a>
     6         </div>
     7     </div>
     8     <h3 th:text="${clientId}+' 请求授权,该应用将获取您的以下信息'"></h3>
     9     <p>昵称,头像和性别</p>
    10     授权后表明您已同意 <a href="javascript:;" style="color: #E9686B">OAUTH-BOOT 服务协议</a>
    11     <form method="post" action="/oauth/authorize">
    12         <input type="hidden" name="user_oauth_approval" value="true" />
    13         <input type="hidden" name="scope.all" value="true" />
    14         <br />
    15         <button class="btn" type="submit">同意/授权</button>
    16     </form>
    17 </div>

    八、配置类和application.properties配置

    1、配置mybatis

    配置SqlSessionFactoryBean

    • 设置数据源
    • 设置包别名
    • 设置mapper映射文件所在的包
     1 @Configuration
     2 public class MyBatisConfiguration {
     3 
     4     @Bean
     5     @Autowired
     6     @ConditionalOnMissingBean
     7     public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource)
     8             throws IOException {
     9 
    10         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    11 
    12         // 设置数据源
    13         sqlSessionFactoryBean.setDataSource(dataSource);
    14 
    15         // 设置别名包
    16         sqlSessionFactoryBean.setTypeAliasesPackage("org.net5ijy.oauth2.bean");
    17 
    18         // 设置mapper映射文件所在的包
    19         PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
    20         String packageSearchPath = "classpath*:org/net5ijy/oauth2/mapper/**.xml";
    21         sqlSessionFactoryBean
    22                 .setMapperLocations(pathMatchingResourcePatternResolver
    23                         .getResources(packageSearchPath));
    24 
    25         return sqlSessionFactoryBean;
    26     }
    27 }
    View Code

    2、配置AuthorizationServerConfigurer

    • 配置使用数据库保存cient信息
    • 配置使用数据库保存token令牌
    • 配置使用数据库保存授权码
     1 @Configuration
     2 public class Oauth2AuthorizationServerConfiguration extends
     3         AuthorizationServerConfigurerAdapter {
     4 
     5     @Autowired
     6     private UserDetailsService userDetailsService;
     7 
     8     @Autowired
     9     private AuthenticationManager authenticationManager;
    10 
    11     @Autowired
    12     private DataSource dataSource;
    13 
    14     @Override
    15     public void configure(ClientDetailsServiceConfigurer clients)
    16             throws Exception {
    17 
    18         // 数据库管理client
    19         clients.withClientDetails(new JdbcClientDetailsService(dataSource));
    20     }
    21 
    22     @Override
    23     public void configure(AuthorizationServerEndpointsConfigurer endpoints)
    24             throws Exception {
    25 
    26         // 用户信息查询服务
    27         endpoints.userDetailsService(userDetailsService);
    28 
    29         // 数据库管理access_token和refresh_token
    30         TokenStore tokenStore = new JdbcTokenStore(dataSource);
    31 
    32         endpoints.tokenStore(tokenStore);
    33 
    34         ClientDetailsService clientService = new JdbcClientDetailsService(
    35                 dataSource);
    36 
    37         DefaultTokenServices tokenServices = new DefaultTokenServices();
    38         tokenServices.setTokenStore(tokenStore);
    39         tokenServices.setSupportRefreshToken(true);
    40         tokenServices.setClientDetailsService(clientService);
    41         // tokenServices.setAccessTokenValiditySeconds(180);
    42         // tokenServices.setRefreshTokenValiditySeconds(180);
    43 
    44         endpoints.tokenServices(tokenServices);
    45 
    46         endpoints.authenticationManager(authenticationManager);
    47 
    48         // 数据库管理授权码
    49         endpoints.authorizationCodeServices(new JdbcAuthorizationCodeServices(
    50                 dataSource));
    51         // 数据库管理授权信息
    52         ApprovalStore approvalStore = new JdbcApprovalStore(dataSource);
    53         endpoints.approvalStore(approvalStore);
    54     }
    55 }
    View Code

    3、配置security

    • 配置使用数据库保存登录用户信息
    • 配置自定义登录页面
    • 暂时禁用CSRF
     1 @EnableWebSecurity
     2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
     3 
     4     @Autowired
     5     private UserDetailsService userDetailsService;
     6 
     7     @Autowired
     8     private PasswordEncoder passwordEncoder;
     9 
    10     @Bean
    11     public PasswordEncoder passwordEncoder() {
    12         return new BCryptPasswordEncoder(); // 使用 BCrypt 加密
    13     }
    14 
    15     public AuthenticationProvider authenticationProvider() {
    16         DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
    17         authenticationProvider.setUserDetailsService(userDetailsService);
    18         authenticationProvider.setPasswordEncoder(passwordEncoder);
    19         authenticationProvider.setHideUserNotFoundExceptions(false);
    20         return authenticationProvider;
    21     }
    22 
    23     @Override
    24     public void configure(WebSecurity web) throws Exception {
    25         web.ignoring().antMatchers("/css/**", "/js/**", "/fonts/**",
    26                 "/icon/**", "/favicon.ico");
    27     }
    28 
    29     @Override
    30     protected void configure(HttpSecurity http) throws Exception {
    31 
    32         http.requestMatchers()
    33                 .antMatchers("/login", "/login-error", "/oauth/authorize",
    34                         "/oauth/token").and().authorizeRequests()
    35                 .antMatchers("/login").permitAll().anyRequest().authenticated();
    36 
    37         // 登录页面
    38         http.formLogin().loginPage("/login").failureUrl("/login-error");
    39 
    40         // 禁用CSRF
    41         http.csrf().disable();
    42     }
    43 
    44     @Autowired
    45     public void configureGlobal(AuthenticationManagerBuilder auth)
    46             throws Exception {
    47         auth.userDetailsService(userDetailsService);
    48         auth.authenticationProvider(authenticationProvider());
    49     }
    50 
    51     public static void main(String[] args) {
    52         System.out.println(new BCryptPasswordEncoder().encode("123456"));
    53     }
    54 }
    View Code

    4、application.properties文件配置

     1 server.port=7001
     2 
     3 ##### Built-in DataSource #####
     4 spring.datasource.url=jdbc:mysql://localhost:3306/test
     5 spring.datasource.username=system
     6 spring.datasource.password=123456
     7 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
     8 
     9 spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
    10 spring.datasource.dbcp2.initial-size=5
    11 spring.datasource.dbcp2.max-active=25
    12 spring.datasource.dbcp2.max-idle=10
    13 spring.datasource.dbcp2.min-idle=5
    14 spring.datasource.dbcp2.max-wait-millis=10000
    15 spring.datasource.dbcp2.validation-query=SELECT 1
    16 spring.datasource.dbcp2.connection-properties=characterEncoding=utf8
    17 
    18 ##### Thymeleaf #####
    19 # 编码
    20 spring.thymeleaf.encoding=UTF-8
    21 # 热部署静态文件
    22 spring.thymeleaf.cache=false
    23 # 使用HTML5标准
    24 spring.thymeleaf.mode=HTML5

    九、受保护资源

     1 @RestController
     2 @RequestMapping(value = "/order")
     3 public class TestController {
     4 
     5     Logger log = LoggerFactory.getLogger(TestController.class);
     6 
     7     @RequestMapping(value = "/demo")
     8     @ResponseBody
     9     public ResponseMessage getDemo() {
    10         Authentication auth = SecurityContextHolder.getContext()
    11                 .getAuthentication();
    12         log.info(auth.toString());
    13         return ResponseMessage.success();
    14     }
    15 }

    十、应用启动类

     1 @SpringBootApplication
     2 @EnableAuthorizationServer
     3 @EnableResourceServer
     4 @MapperScan("org.net5ijy.oauth2.repository")
     5 public class Oauth2Application {
     6 
     7     public static void main(String[] args) {
     8 
     9         // args = new String[] { "--debug" };
    10 
    11         SpringApplication.run(Oauth2Application.class, args);
    12     }
    13 }

    十一、测试授权码模式

    1、获取authorization_code授权码

    使用浏览器访问:
    http://localhost:7001/oauth/authorize?response_type=code&client_id=net5ijy&redirect_uri=http://localhost:8080&scope=all

    地址
    http://localhost:7001/oauth/authorize

    参数

    response_type

    code

    client_id

    根据实际的client-id填写,此处写net5ijy

    redirect_uri

    生成code后的回调地址,http://localhost:8080

    scope

    权限范围

    登录,admin001和123456

    允许授权

    看到浏览器重定向到了http://localhost:8080并携带了code参数,这个code就是授权服务器生成的授权码

    2、获取token令牌

    使用curl命令获取token令牌

    curl --user net5ijy:123456 -X POST -d "grant_type=authorization_code&scope=all&redirect_uri=http%3a%2f%2flocalhost%3a8080&code=ubtvR4" http://localhost:7001/oauth/token

    地址
    http://localhost:7001/oauth/token

    参数

    grant_type

    授权码模式,写authorization_code

    scope

    权限范围

    redirect_uri

    回调地址,http://localhost:8080需要urlencode

    code

    就是上一步生成的授权码

    返回值

    1 {
    2     "access_token": "c5836918-1924-4b0a-be67-043218c6e7e0",
    3     "token_type": "bearer",
    4     "refresh_token": "7950b7f9-7d60-41da-9a95-bd2c8b29ada1",
    5     "expires_in": 7199,
    6     "scope": "all"
    7 }

    这样就获取到了token令牌,该token的访问权限范围是all权限,在2小时后失效。

    3、使用token访问资源

    http://localhost:7001/order/demo?access_token=c5836918-1924-4b0a-be67-043218c6e7e0

  • 相关阅读:
    iOS UIScrollView 停止滑动 减速
    移动App-UI配制篇
    pathload --有效的网络带宽估计方法
    页面提交错误,页面间参数传递java.lang.NumberFormatException: null
    jquery easyui Accordion的使用
    利用开源HTML5引擎lufylegend.js结合javascript实现的五子棋人机对弈
    POJ 3221 Diamond Puzzle(BFS)
    信息管理系统怎样获取当前日期时间
    Unity3d-XML文件数据解析&amp;JSON数据解析
    oracle data file header replace(測)
  • 原文地址:https://www.cnblogs.com/xugf/p/10726881.html
Copyright © 2011-2022 走看看