【SpringSecurity+OAuth2+JWT入门到实战】4.系统配置自定义登录页面

编程

关于个性化配置全部在spring-security-browser项目的BrowserSecurityConfig完成。

自定义登录页面

创建登录页面

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>标准登录页面</title>

</head>

<body>

<h2>标准登录页面</h2>

<h3>表单登录</h3>

<form action="/authentication/form" method="post">

<table>

<tr>

<td>用户名:</td>

<td><input type="text" name="username"></td>

</tr>

<tr>

<td>密码:</td>

<td><input type="password" name="password"></td>

</tr>

<tr>

<td colspan="2">

<button type="submit">登录</button>

</td>

</tr>

</table>

</form>

</body>

</html>

注意这里的路径:acrion="/authentication/form";路径是自定义的, 
而UsernamePasswordAuthenticationFilter默认是处理/login路径的登录请求。下面配置解决这个问题

public UsernamePasswordAuthenticationFilter() {

super(new AntPathRequestMatcher("/login", "POST"));

}

 

在BrowserSecurityConfig类重写configure方法

@Override

protected void configure(HttpSecurity http) throws Exception {

//配置

}

package com.spring.security;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration

public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

@Bean

public PasswordEncoder passwordEncoder() {

return new BCryptPasswordEncoder();

}

@Override

protected void configure(HttpSecurity http) throws Exception {

//配置

http

.formLogin()

.loginPage("/signIn.html")//登录页面路径

// 处理登录请求路径

.loginProcessingUrl("/authentication/form")

.and()

.authorizeRequests() // 授权配置

//不需要认证的路径

.antMatchers("/signIn.html").permitAll()

.anyRequest() // 所有请求

.authenticated() // 都需要认证

.and().csrf().disable();

}

}

 

启动项目测试:http://127.0.0.1:8080/hello

 处理不同类型的请求

我们做的是一个可重复使用的框架登录页面可能是多个,现在解决这个问题

在spring-security-browser项目创建自定义Controller

package com.spring.security;

import com.spring.security.support.SimpleResponse;

import org.apache.commons.lang3.StringUtils;

import org.springframework.http.HttpStatus;

import org.springframework.security.web.DefaultRedirectStrategy;

import org.springframework.security.web.RedirectStrategy;

import org.springframework.security.web.savedrequest.HttpSessionRequestCache;

import org.springframework.security.web.savedrequest.RequestCache;

import org.springframework.security.web.savedrequest.SavedRequest;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

@RestController

public class BrowserSecurityController {

// 封装了引发跳转请求的工具类,从session中获取

private RequestCache requestCache = new HttpSessionRequestCache();

// spring的工具类:封装了所有跳转行为策略类

private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

/**

* 需要身份认证时跳转到这里

*

* @param request

* @param response

* @return

* @throws IOException

*/

@RequestMapping("/authentication/require")

@ResponseStatus(code = HttpStatus.UNAUTHORIZED)

public SimpleResponse requirAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {

SavedRequest savedRequest = requestCache.getRequest(request, response);

// 如果有引发认证的请求

// spring 在跳转前应该会把信息存放在某个地方?

if (savedRequest != null) {

String targetUrl = savedRequest.getRedirectUrl();

System.out.println("引发跳转的请求:" + targetUrl);

// 如果是html请求,则跳转到登录页

if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {

redirectStrategy.sendRedirect(request, response, "这里填写要跳转的页面先不写,等等从配置文件读取");

}

}

// 否则都返回需要认证的json串

return new SimpleResponse("访问的服务需要身份认证!");

}

}

在spring-security-browser项目创建返回值类

package com.spring.security.support;

import lombok.Data;

@Data

public class SimpleResponse {

private Object content;

public SimpleResponse(Object content) {

this.content = content;

}

}

解决自定义跳转的登录页面,读取yml

修改spring-security-demo项目application.yml

spring:

datasource:

driver-class-name: com.mysql.jdbc.Driver

url: jdbc:mysql://127.0.0.1/auto_test?useUnicode=yes&characterEncoding=UTF-8&useSSL=false

username: root

password: 123456

hk:

security:

browser:

loginPage: /demoLogin.html #登录页面

关于系统配置的封装,SecurityProperties最外层封装包含BrowserProperties(浏览器相关系统配置),ValidateCodeProperties(验证码相关系统配置),OAuth2Properties(权限相关系统配置);

在spring-security-core项目新建SecurityProperties类:

package com.spring.security.properties;

import lombok.Data;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**

* 安全属性

*/

@Data

@ConfigurationProperties(prefix = "hk.security")

public class SecurityProperties {

private BrowserProperties browser = new BrowserProperties();

}

同目录BrowserProperties类

package com.spring.security.properties;

import lombok.Data;

/**

* 浏览器的属性

*/

@Data

public class BrowserProperties {

/**

* 登录页面 默认登录页signIn.html

*/

private String loginPage = "/signIn.html";

}

要想让上面的配置生效还需要加一个SecurityCoreConfig类

在core项目新建:

package com.spring.security.config;

import com.spring.security.properties.SecurityProperties;

import org.springframework.boot.context.properties.EnableConfigurationProperties;

import org.springframework.context.annotation.Configuration;

/**

* 安全核心配置

* SecurityProperties 生效

*/

@Configuration

@EnableConfigurationProperties(SecurityProperties.class)

public class SecurityCoreConfig {

}

改造BrowserSecurityController读取系统配置

package com.spring.security;

import com.spring.security.properties.SecurityProperties;

import com.spring.security.support.SimpleResponse;

import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.http.HttpStatus;

import org.springframework.security.web.DefaultRedirectStrategy;

import org.springframework.security.web.RedirectStrategy;

import org.springframework.security.web.savedrequest.HttpSessionRequestCache;

import org.springframework.security.web.savedrequest.RequestCache;

import org.springframework.security.web.savedrequest.SavedRequest;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseStatus;

import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

@RestController

public class BrowserSecurityController {

// 封装了引发跳转请求的工具类,从session中获取

private RequestCache requestCache = new HttpSessionRequestCache();

// spring的工具类:封装了所有跳转行为策略类

private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

@Autowired

private SecurityProperties securityProperties;

/**

* 需要身份认证时跳转到这里

*

* @param request

* @param response

* @return

* @throws IOException

*/

@RequestMapping("/authentication/require")

@ResponseStatus(code = HttpStatus.UNAUTHORIZED)

public SimpleResponse requirAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException {

SavedRequest savedRequest = requestCache.getRequest(request, response);

// 如果有引发认证的请求

// spring 在跳转前应该会把信息存放在某个地方?

if (savedRequest != null) {

String targetUrl = savedRequest.getRedirectUrl();

System.out.println("引发跳转的请求:" + targetUrl);

// 如果是html请求,则跳转到登录页

if (StringUtils.endsWithIgnoreCase(targetUrl, ".html")) {

redirectStrategy.sendRedirect(request, response, securityProperties.getBrowser().getLoginPage());

}

}

// 否则都返回需要认证的json串

return new SimpleResponse("访问的服务需要身份认证!");

}

}

现在demo项目系统配置登录页面为:demoLogin.html

demo项目新建demoLogin.html页面:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo登录页面</title>

</head>

<body>

<h2>demo登录页面</h2>

</body>

</html>

改造BrowserSecurityConfig类不拦截登录页

package com.spring.security;

import com.spring.security.properties.SecurityProperties;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.security.config.annotation.web.builders.HttpSecurity;

import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration

public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired

private SecurityProperties securityProperties;

@Bean

public PasswordEncoder passwordEncoder() {

return new BCryptPasswordEncoder();

}

@Override

protected void configure(HttpSecurity http) throws Exception {

//配置

http

.formLogin()

.loginPage("/authentication/require")//登录页面路径

// 处理登录请求路径

.loginProcessingUrl("/authentication/form")

.and()

.authorizeRequests() // 授权配置

//不需要认证的路径

.antMatchers("/authentication/require","/signIn.html",securityProperties.getBrowser().getLoginPage()).permitAll()

.anyRequest() // 所有请求

.authenticated() // 都需要认证

.and().csrf().disable();

}

}

启动项目访问:http://127.0.0.1:8080/hello

访问:http://127.0.0.1:8080/index.html

注释掉系统配置:

#hk:

# security:

# browser:

# loginPage: /demoLogin.html #登录页面

重启项目访问:http://127.0.0.1:8080/index.html

以上是 【SpringSecurity+OAuth2+JWT入门到实战】4.系统配置自定义登录页面 的全部内容, 来源链接: utcz.com/z/514022.html

回到顶部