Spring boot+Security OAuth2 自定义登录和授权页面

2023-05-16

在学习了Spring Security oAuth2.0框架的基础知识,以及动手搭建简单的认证服务器和资源服务器的基础上,我们开始实现自定义登陆和授权界面的开发。

 

在实际的项目开发中,我们需要根据需要自定义oAuth2.0的登陆和授权界面。以下是具体的开发步骤:

第一步:首先需要引入thymeleaf 模板引擎(Spring boot框架推荐使用thymeleaf开发前端界面)


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

第二步:在spring boot工程的application.yml配置文件中配置thymeleaf

spring:
  application:
    name: oauth2-server
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    jdbc-url: jdbc:mysql://10.111.31.28:3306/oauth2?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root
    hikari:
      minimum-idle: 5
      idle-timeout: 600000
      maximum-pool-size: 10
      auto-commit: true
      pool-name: MyHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
      connection-test-query: SELECT 1

  thymeleaf:
    prefix: classpath:/views/
    suffix: .html
    cache: false
  mvc:
    throw-exception-if-no-handler-found: true
    
server:
  port: 8080

mybatis:
  type-aliases-package: com.funtl.oauth2.server.domain
  mapper-locations: classpath:mapper/*.xml
  

第三步:登陆界面,授权界面重新设计

自定义登录页面肯定要有自己的页面,先从页面入手,在resources 目录下新建views 目录,在此目录下新建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">
        <p class="title">用户登录</p>
        <form name="loginForm" method="post" th:action="${loginProcessUrl}">
            <input type="text" name="username" placeholder="用户名"/>
            <br>
            <input type="password" name="password" placeholder="密码"/>
            <br>
            <button type="submit" class="btn">登 &nbsp;&nbsp; 录</button>
        </form>
        <p style="color: red" th:if="${param.error}">用户名或密码错误</p>
    </div>
</div>
</body>
</html>

在views文件夹下新建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">OAUTH-BOOT 授权</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">OAUTH-BOOT 服务协议</a>
        <form method="post" action="/oauth/authorize">  

        <input type="hidden" name="user_oauth_approval" value="true">
        <input type="hidden" name="_csrf" th:value="${_csrf.getToken()}"/>

        <div th:each="item:${scopes}">
            <input type="radio" th:name="'scope.'+${item}" value="true" hidden="hidden" checked="checked"/>
        </div>

        <button class="btn" type="submit"> 同意/授权</button>

    </form>
    </div>
</body>
</html>

第四步:定义Controller

登陆界面Controller

package com.funtl.oauth2.server.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.provider.AuthorizationRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class BaseMainController {  
    
    @GetMapping("/auth/login")
    public String loginPage(Model model){  
    	
        model.addAttribute("loginProcessUrl","/auth/authorize");
    	
        return "base-login";
    }
}

WebSecurity 配置

授权前的用户认证有Security 提供,将自定义的登录页面配置进去

package com.funtl.oauth2.server.config;

import com.funtl.oauth2.server.config.service.UserDetailsServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
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.builders.WebSecurity;
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.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        // 设置默认的加密方式
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // 使用自定义认证与授权
        auth.userDetailsService(userDetailsService());
    }
    

    @Override
    public void configure(WebSecurity web) throws Exception {
        // 将 check_token 暴露出去,否则资源服务器访问时报 403 错误
        web.ignoring().antMatchers("/oauth/check_token");
    }
    
    @Override  
    protected void configure(HttpSecurity http) throws Exception {
 
        http
                // 必须配置,不然OAuth2的http配置不生效----不明觉厉
                .requestMatchers()
                .antMatchers("/auth/login", "/auth/authorize","/oauth/authorize")
                .and()
                .authorizeRequests()
                // 自定义页面或处理url是,如果不配置全局允许,浏览器会提示服务器将页面转发多次
                .antMatchers("/auth/login", "/auth/authorize")
                .permitAll()
                .anyRequest()
                .authenticated();
        
        // 表单登录
        http.formLogin()
                // 登录页面
                .loginPage("/auth/login")
                // 登录处理url
                .loginProcessingUrl("/auth/authorize");
        http.httpBasic().disable();
    }

}

到这里已经完成了自定义登录页的功能,接下来继续说自定义授权页面

自定义授权页面

授权Controller

package com.funtl.oauth2.server.controller;

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")  
	 @RequestMapping("/custom/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");

        view.addObject("clientId", authorizationRequest.getClientId());

        view.addObject("scopes",authorizationRequest.getScope());

        return view;
    }

}

 在认证服务配置文件AuthorizationServerConfiguration中添加如下配置

 @Override  
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
    	
        。。。。。。。。。。。。。  
        // 最后一个参数为替换之后授权页面的url
        endpoints.pathMapping("/oauth/confirm_access","/custom/confirm_access");
              
    }

最后即可开始测试:

效果图如下

å¨è¿éæå¥å¾çæè¿°

 

源码地址 

https://download.csdn.net/download/u013310119/11275096

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring boot+Security OAuth2 自定义登录和授权页面 的相关文章

随机推荐

  • 在Windows端使用XShell、WinSCP连接WSL2(win10的linux子系统/Ubuntu)

    一 安装SSH服务 1 在ubuntu中输入 sudo apt get install openssh server 2 开启ssh服务 sudo service ssh start 二 在Windows Subsystem for Lin
  • 迷失的RPC.getServer方法

    今天学习了有关RPC的有关知识 xff0c RPC remote procedure call 是一种 远程过程调用协议 xff0c 它是一种通过网络从远程计算机程序上请求服务 xff0c 而不需要了解底层网络技术的协议 RPC是hadoo
  • 吃透Redis(十一):Redis原子性的保证

    redis原子性保证 Redis server 一旦和一个客户端建立连接后 xff0c 就会在事件驱动框架中注册可读事件 xff0c 这就对应了客户端的命令请求 而对于整个命令处理的过程来说 xff0c 我认为主要可以分成四个阶段 xff1
  • Matlab编程技巧:A*算法仿真

    本文通过Matlab编程实现A 算法 xff0c 并通过几个简单的例子 xff0c 打断点调试输出A 搜索的过程 文章目录 1 A 算法简介2 Matlab编程实现2 1 输入参数2 2 初始化变量2 3 循环过程2 4 循环后处理 3 调
  • python中np.max与np.maximum的区别

    在使用numpy的时候 xff0c 我们会遇到取最大的问题 xff0c 常用的函数有两个 xff1a np max与np maximum xff0c 那么它们的主要区别在哪里呢 xff1f np max a axis 61 None out
  • Linux下网络编程5种实现(源代码)

    学习整理Linux网络编程5种服务器模型多线程 多进程 Select Poll Epoll实现源代码 xff0c 注释较为详细 xff0c 方便初学者学习 1 简单阻塞式客户端服务器实现 xff1a 如若链接打不开 xff0c 复制网址到浏
  • Proxifier使用教程

    https blog csdn net u013066730 article details 88788191 很详细 另外shadowshocks代理服务器的IP地址 地址获取 win 43 R cmd ipconfig 无线网区域的ip
  • Pascal's Triangle II:节省空间杨辉三角

    Given an index k return the k th row of the Pascal 39 s triangle For example given k 61 3 Return 1 3 3 1 Note Could you
  • rl: (7) Failed to connect to get.rvm.io port 443: Operation timed out

    问题 xff1a curl L https get rvm io bash s stable 命令失败 报错内容 xff1a rl 7 Failed to connect to get rvm io port 443 Operation t
  • 微信公众号授权scope参数错误或没有scope权限

    背景描述 xff1a 使用微信公众号测试号进行微信公众号开发 xff0c 配置完公众号菜单之后 xff0c 点击按钮 xff0c 调转出现白页 xff0c 并提示 xff1a 微信公众号授权scope参数错误或没有scope权限 xff1b
  • LDAP统一认证服务解决方案

    LDAP是什么 首先LDAP是一种通讯协议 xff0c LDAP支持TCP IP 协议就是标准 xff0c 并且是抽象的 在这套标准下 xff0c AD xff08 Active Directory xff09 是微软出的一套实现 那AD是
  • 2021-07-02随笔JAVA面试题

    List和Set的区别 List和Set都是接口 他们各自有自己的实现类 有无顺序的实现类 也有有顺序的实现类 最大的不同就是List是可以重复的 而Set是不能重复的 List适合经常追加数据 插入 删除数据 但随即取数效率比较低 Set
  • 从用户管理系统中复习javaweb知识9

    前面我们算是基本完成了用户注册这个功能 xff0c 但是也是仅仅实现了这个功能 xff0c 在实际应用中我们不能这么做 xff0c 而且用户也不会接受我们这样做 我们要做的还有很多 比如 xff0c 用户注册的时候填写用户名的时候我们得先验
  • 20210704 JAVA Redis和Memcached的一些区别

    什么是Memcache Memcache集群环境下缓存解决方案 Memcache是一个高性能的分布式的内存对象缓存系统 通过在内存里维护一个统一的巨大的hash表 它能够用来存储各种格式的数据 包括图像 视频 文件以及数据库检索的结果等 简
  • RocketMQ中ACL权限控制

    1 什么是ACL ACL是access control list的简称 xff0c 俗称访问控制列表 访问控制 xff0c 基本上会涉及到用户 资源 权限 角色等概念 xff0c 那在RocketMQ中上述会对应哪些对象呢 xff1f 用户
  • Removing obsolete files from server... Could not clean server of obsolete files: Premature end of fi

    Tomcat启动报如下错误 xff1a Removing obsolete files from server Could not clean server of obsolete files Premature end of file P
  • 数据库索引的作用优点和缺点

    为什么要创建索引呢 xff1f 这是因为 xff0c 创建索引可以大大提高系统的性能 第一 xff0c 通过创建唯一性索引 xff0c 可以保证数据库表中每一行数据的唯一性 第二 xff0c 可以大大加快 数据的检索速度 xff0c 这也是
  • Linux下开启和关闭Telnet服务

    码都不扫 xff0c 怎么扫Bug telnet与ssh相比 xff0c 安全性能并不高 xff0c 但是在SSH版本升级或者其他的情况下还是需要开启这一服务 linux提供服务是由运行在后台的守护程序 xff08 daemon xff09
  • java调用HTTP接口(Get请求和Post请求)

    敢扫吗 xff0c 不敢的话 xff0c 就别扫了 前提 xff1a 一个Http接口 xff1a http 172 83 38 209 7001 NSRTRegistration test add do id 61 8888888 amp
  • Spring boot+Security OAuth2 自定义登录和授权页面

    在学习了Spring Security oAuth2 0框架的基础知识 xff0c 以及动手搭建简单的认证服务器和资源服务器的基础上 xff0c 我们开始实现自定义登陆和授权界面的开发 在实际的项目开发中 xff0c 我们需要根据需要自定义