上篇 Spring boot+Security OAuth2 爬坑日记(2)
1. 依赖
<!---------thymeleaf 模板引擎-------->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
thymeleaf
配置
spring:
thymeleaf:
prefix: classpath:/views/
suffix: .html
cache: false
2. 前端页面
自定义登录页面肯定要有自己的页面,先从页面入手,在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()}"/>
<button class="btn" type="submit"> 同意/授权</button>
</form>
</div>
</body>
</html>
3. Controller
登录页面controller如下
@Controller
public class BaseMainController {
@Autowired
private BootSecurityProperties properties;
@GetMapping("/auth/login")
public String loginPage(Model model){
model.addAttribute("loginProcessUrl",properties.getLoginProcessUrl());
return "base-login";
}
}
4. WebSecurity
配置
授权前的用户认证有Security 提供,将自定义的登录页面配置进去
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private BootUserDetailService userDetailService;
@Autowired
private BootSecurityProperties properties;
/**
* 让Security 忽略这些url,不做拦截处理
*
* @param
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers
("/swagger-ui.html/**", "/webjars/**",
"/swagger-resources/**", "/v2/api-docs/**",
"/swagger-resources/configuration/ui/**", "/swagger-resources/configuration/security/**",
"/images/**");
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
// 配置当前http security要生效的url
.requestMatchers()
.antMatchers("/auth/login", properties.getLoginProcessUrl(), "/oauth/authorize")
.and()
.authorizeRequests()
// 自定义页面或处理url是,如果不配置全局允许,浏览器会提示服务器将页面转发多次
.antMatchers("/auth/login", properties.getLoginProcessUrl())
.permitAll()
.anyRequest()
.authenticated();
// 表单登录
http.formLogin()
// 登录页面
.loginPage("/auth/login")
// 登录处理url
.loginProcessingUrl(properties.getLoginProcessUrl());
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
到这里已经完成了自定义登录页的功能,接下来继续说自定义授权页面
5. 自定义授权页面
自定义授权页面的方式有两种,分别如下;
(1). 直接定义如下controller 替换原来的授权controller
@Controller
// 必须配置
@SessionAttributes("authorizationRequest")
public class BootGrantController {
@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());
return view;
}
}
(2). 在认证服务配置文件中添加如下配置
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
......
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
......
// 最后一个参数为替换之后页面的url
endpoints.pathMapping("/oauth/confirm_access","/custom/confirm_access");
}
}
之后编写对应的controller实现即可
6. 测试
最终效果如下
下一篇 Spring boot+Security OAuth2 爬坑日记(4)自定义异常处理 上
微信公众号
GitHub 博客地址