主要说明:基于若依springcloud微服务框架的2.1版本

嫌弃缩进不舒服的,直接访问我的博客站点:
http://binarydance.top//aticle_view.html?aticle_id=603216759344082944&t=1623984554005
一开始网上教程一堆,都是各抄各的,有的直接代码缺少,有的直接不可以用(MLGB的),于是乎去spring官网找找看,还真找到,最终自己配置搭建成功跑了一遍demo,美滋滋。一些HTML文件还是网上的,见谅~

由于是springcloud项目(注册和配置中心是nacos),认证中心在auth模块,自己demo搭建测试直接在auth模块,没有走网关gateway

目前测试的scope只有一个:server,见表:sys_oauth_client_details

sys_oauth_client_details表:

CREATE TABLE `sys_oauth_client_details` (`client_id` varchar(255) NOT NULL COMMENT '终端编号',`resource_ids` varchar(255) DEFAULT NULL COMMENT '资源ID标识',`client_secret` varchar(255) NOT NULL COMMENT '终端安全码',`scope` varchar(255) NOT NULL COMMENT '终端授权范围',`authorized_grant_types` varchar(255) NOT NULL COMMENT '终端授权类型',`web_server_redirect_uri` varchar(255) DEFAULT NULL COMMENT '服务器回调地址',`authorities` varchar(255) DEFAULT NULL COMMENT '访问资源所需权限',`access_token_validity` int(11) DEFAULT NULL COMMENT '设定终端的access_token的有效时间值(秒)',`refresh_token_validity` int(11) DEFAULT NULL COMMENT '设定终端的refresh_token的有效时间值(秒)',`additional_information` varchar(4096) DEFAULT NULL COMMENT '附加信息',`autoapprove` tinyint(4) DEFAULT NULL COMMENT '是否登录时跳过授权',`origin_secret` varchar(255) NOT NULL COMMENT '终端明文安全码',PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='终端配置表';
INSERT INTO `sys_oauth_client_details` VALUES ('web', '', '$2a$10$t.Hw9Nu.lWp5iK9I7MZRCuX9EeV2DNu6xj9wunfD5ZclvQSdoBo5O', 'server', 'password,refresh_token,authorization_code,implicit,client_credentials', 'https://www.baidu.com', NULL, 604800, 1209600, NULL, NULL, '123456');

Spring Security Oauth2 的maven坐标:

    <!-- Spring Security Oauth2 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId><version>2.2.1.RELEASE</version></dependency>

项目配置:

# Tomcat
server: port: 9200# Spring
spring: application:# 应用名称name: my-authprofiles:# 环境配置active: devcloud:nacos:discovery:# 服务注册地址server-addr: 192.168.1.39:8848config:# 配置中心地址server-addr: 192.168.1.39:8848# 配置文件格式file-extension: yml# 共享配置shared-configs: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}main: allow-bean-definition-overriding: true

引入模板解析引擎:

        <!-- thymeleaf 模板引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>

AuthorizationServerConfigurerAdapter无需改动,你的是什么就是什么:

@Configuration
@EnableAuthorizationServer
@Slf4j
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
// 无需改动,你的是什么就是什么
......
}

上面是基础,关键来了:
resources下面建立static目录,放置登录页面(注意:form表单action="/login"):base-login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>登录</title>
</head><style>.login-container {margin: 50px;width: 100%;}.form-container {margin: 0px auto;width: 50%;text-align: center;box-shadow: 1px 1px 10px #888888;height: 300px;padding: 5px;}input {margin-top: 10px;width: 350px;height: 30px;border-radius: 3px;border: 1px #E9686B solid;padding-left: 2px;}.btn {width: 350px;height: 35px;line-height: 35px;cursor: pointer;margin-top: 20px;border-radius: 3px;background-color: #E9686B;color: white;border: none;font-size: 15px;}.title{margin-top: 5px;font-size: 18px;color: #E9686B;}</style>
<body>
<div class="login-container"><div class="form-container">       <form class="form-signin" method="post" action="/login"><h2 class="form-signin-heading">用户登录</h2><p><label for="username" class="sr-only">用户名</label><input type="text" id="username" name="username" class="form-control" placeholder="用户名" required autofocus></p><p><label for="password" class="sr-only">密码</label><input type="password" id="password" name="password" class="form-control" placeholder="密码" required></p><button class="btn btn-lg btn-primary btn-block" type="submit">&nbsp;&nbsp;</button></form></div>
</div>
</body>
</html>

配置WebSecurityConfigurerAdapter:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;/*** Security 安全认证相关配置*/
@Order(99)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailsService;@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}/*** 配置修改hideUserNotFoundExceptions = false,不隐藏usernameNotFundExceptions* @return*/@Beanpublic DaoAuthenticationProvider authenticationProvider() {DaoAuthenticationProvider provider = new DaoAuthenticationProvider();provider.setHideUserNotFoundExceptions(false);provider.setUserDetailsService(userDetailsService);provider.setPasswordEncoder(passwordEncoder());return provider;}@Bean@Overridepublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(authenticationProvider());}  @Overrideprotected void configure(HttpSecurity http) throws Exception { http.formLogin().loginPage("/base-login.html") //自定义的登录页面 **重要**.loginProcessingUrl("/login")  //原始的处理登录的URL,保持和base-login.html的form表单的action一致 **重要**.permitAll() //放开 **重要**.and().requestMatchers().antMatchers("/oauth/**","/login/**","/logout/**")// **重要**.and().authorizeRequests()   .antMatchers("/xxx/**",).permitAll()//一些需要放开的URL.anyRequest().authenticated().and().headers().frameOptions().disable().and().csrf().disable();}
}

到此登录页面自定义完成。别急,还有自定义授权页面呢。

在resources目录下面建立templates目录,放置授权页面(注意:form表单action="/oauth/authorize"):base-grant.html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>授权</title>
</head>
<style>html{padding: 0px;margin: 0px;}.title {background-color: #E9686B;height: 50px;padding-left: 20%;padding-right: 20%;color: white;line-height: 50px;font-size: 18px;}.title-left{float: right;}.title-right{float: left;}.title-left a{color: white;}.container{clear: both;text-align: center;}.btn {width: 350px;height: 35px;line-height: 35px;cursor: pointer;margin-top: 20px;border-radius: 3px;background-color: #E9686B;color: white;border: none;font-size: 15px;}</style>
<body style="margin: 0px">
<div class="title"><div class="title-right">oauth2授权</div><div class="title-left"><a href="#help">帮助</a></div>
</div><div class="container"><h3 th:text="${clientId}+' 请求授权,该应用将获取你的以下信息'"></h3><p>昵称,头像和性别</p>授权后表明你已同意 <a  href="#boot" style="color: #E9686B">服务协议</a><form method="post" action="/oauth/authorize"><input type="hidden" name="user_oauth_approval" value="true"><div th:each="item:${scopes}"><input type="radio" th:name="'scope.'+${item}" value="true" checked>同意 <input type="radio" th:name="'scope.'+${item}" value="false" >拒绝</div><input name="authorize" value="同意/授权" type="submit"></form></div>
</body>
</html>

同时,controller覆盖oauth2的方法:

import java.util.Map;import javax.servlet.http.HttpServletRequest;import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;@Controller
//必须配置
@SessionAttributes("authorizationRequest")
public class BootGrantController {@RequestMapping("/oauth/confirm_access")public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception {AuthorizationRequest authorizationRequest = (AuthorizationRequest) model.get("authorizationRequest");ModelAndView view = new ModelAndView();view.setViewName("base-grant"); //自定义页面名字,resources\templates\base-grant.htmlview.addObject("clientId", authorizationRequest.getClientId());view.addObject("scopes",authorizationRequest.getScope());return view;}
}

至此,自定义登录页面、授权页面完成。

①获取授权码code(注意:client_id=web):

http://192.168.1.39:9200/oauth/authorize?response_type=code&client_id=web&redirect_uri=https://www.baidu.com&scope=server

第一次访问上面地址获取授权码code,先会跳转至自定义登录页面:

输入账号密码,跳转至授权页面:

同意之后,跳转到我们设定的redirect_uri=https://www.baidu.com,同时获取授权码code(牛逼,这样图片也违规,去我博客站点看吧~):

②根据上面获取的授权码code=rLePQ8获取访问的token:

至此流程完成,等到我们的token
③根据token去访问你需要的资源吧。

特别说明的是:第一次授权以后获取授权码code,之后获取授权码code直接收入账号、密码后立即返回授权码code,并不会再一次要求用户进入授权页面(base-grant.html)允许、拒绝选择操作。

如果希望默认就是授权,不需要跳出授权页面(base-grant.html),那么sys_oauth_client_details表中,autoapprove(是否登录时跳过授权)设置为true(值:1)即可。

Spring Security Oauth2 授权码模式下 自定义登录、授权页面(演示)

Spring Security Oauth2 授权码模式下 自定义登录、授权页面相关推荐

  1. 【Spring Cloud Alibaba 实战 | 总结篇】Spring Cloud Gateway + Spring Security OAuth2 + JWT 实现微服务统一认证授权和鉴权

    一. 前言 hi,大家好~ 好久没更文了,期间主要致力于项目的功能升级和问题修复中,经过一年时间这里只贴出关键部分代码的打磨,[有来]终于迎来v2.0版本,相较于v1.x版本主要完善了OAuth2认证 ...

  2. Spring Security OAuth2源码解析(一)

    目录 引入 AuthorizationServerEndpointsConfiguration 属性 AuthorizationEndpoint OAuth2RequestFactory Defaul ...

  3. Spring Security Oauth2 之密码模式

    点击关注公众号,实用技术文章及时了解   作者:歪桃   blog.csdn.net/m0_37892044/article/details/113058924 前言,因为最近的项目是用Spring ...

  4. 使用Spring Security Oauth2 和 JWT保护微服务--Uaa授权服务器的编写

    学习自深入理解微服务 采用Spring Security OAuth2 和 JWT的方式,Uaa服务只需要验证一次,返回JWT.返回的JWT包含了用户的所有信息,包括权限信息 从三个方面讲解: JWT ...

  5. JWT实战 Spring Security Oauth2整合JWT 整合SSO单点登录

    文章目录 一.JWT 1.1 什么是JWT 1.2 JWT组成 头部(header) 载荷(payload) 签名(signature) 如何应用 1.3 JJWT 快速开始 创建token toke ...

  6. Spring Security OAuth2源码解析(三)——单点登录。

    引入 @EnableOAuth2Client @EnableConfigurationProperties(OAuth2SsoProperties.class) @Import({ OAuth2Sso ...

  7. Spring Security 实战干货:玩转自定义登录

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 前面的关于 Spring Security  ...

  8. Spring Security OAuth2源码解析(二)

    鉴权服务器对客户端鉴权之后,会生成token,客户端使用token,就可以去资源服务器获取资源. @EnableResourceServer  @Import(ResourceServerConfig ...

  9. 实战讲解Spring Oauth2.0密码模式和授权码模式(内存inMemory+持久化jdbc配置)

    1 缘起 先吐槽, 在搜索关于Oauth2.0授权码方式认证时, 遇到的问题比较多,一句话,按照其分享的步骤一步一步来,最终,无法成功, 本想,抄近路,看一些前人分享的应用案例,直接使用, 近路不通, ...

最新文章

  1. python自学教程推荐-学习python中的pandas有没有好的教程推荐?
  2. Computer:计算机测试理论(开发/测试/上线)之DEV、SIT、UAT、PRD四套环境详细介绍之详细攻略
  3. 空间谱专题16:间距选取分析
  4. vmware workstation17环境安装centos7
  5. python入门指南_Python中的逻辑门–入门指南
  6. 重构第0天--重构的理解
  7. 浅谈算法和数据结构: 十二 无向图相关算法基础
  8. java创建http接口
  9. 车间和仓库可以一起吗_为什么厂房和仓库不能混用?
  10. 5. 位操作指令 AND,ORR, TST,BIC
  11. alt+w热键组合无法使用
  12. i3cpu驱动xp_Intel英特尔 Core i3/Core i5/Core i7系列CPU显示驱动 14.46.9.5394版 For WinXP-32...
  13. 天池精准医疗大赛——人工智能辅助糖尿病遗传风险预测
  14. 面试题:构造方法中可不可以有return语句呢?
  15. 【python种子项目ppc】保姆级别指导给项目添加测试
  16. 自学java面向实习从零开始路线
  17. GOM引擎传奇调整音量设置一次关闭音量和逐渐降低设置方法
  18. jquery 添加点击添加class样式 移除兄弟元素样式
  19. fatal error C1083: 无法打开预编译头文件 的解决方法
  20. 计算机应用高级课程,Rsoft软件高级课程

热门文章

  1. java 图类_java笔记之图形类详解
  2. 首发!小牛电动股权巨震:李一男、胡依林大幅减持,纪源资本退出
  3. 百会观点:用CRM深度维护老客户
  4. oracle查询blob模糊搜索,BLOB字段模糊查询
  5. vue 项目中使用wangEditor上传图片视频到oos
  6. 模糊控制系统模糊控制器模块(二)---知识库
  7. linux硬盘盘符更改,linux更改emc磁盘盘符
  8. 一文概览2D人体姿态估计
  9. 如何清理hue元数据库里面的历史数据
  10. Zabbix-proxy安装(zabbix 6.0LTS)