赞
踩
在学习了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">登 录</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");
-
- }
最后即可开始测试:
效果图如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。