自定义界面登入,使用了部分别人的代码,登入界面我是使用别人的,本篇内容还顺道解决一个问题,具体原理我这边没时间去查了 只是解决了下。
第一步:添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>my-springboot-git</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!--spring-security-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!--spring-security-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<!--添加相关资源-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<excludes>
<exclude>**/*.yml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
</build>
</project>
第二步:添加配置类
@Configuration
@EnableWebSecurity
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
Logger logger = LoggerFactory.getLogger(MyWebSecurityConfig.class);
@Autowired
private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;
@Autowired
private MyAuthenticationFailureHandler myAuthenticationFailureHandler;
/**
* 设置登入密码加密格式
* @return
*/
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
//
// public static void main(String[] args) {
// BCryptPasswordEncoder BCryptPasswordEncoder =new BCryptPasswordEncoder();
// System.out.println(BCryptPasswordEncoder.encode("123"));
// }
@Override
protected void configure(HttpSecurity http) throws Exception {
logger.info("MyWebSecurityConfig-->configure");
http
// 开始请求权限配置
.authorizeRequests()
//去除静态资源和swagger和无需拦截地址
.antMatchers("/test/**").permitAll()
.anyRequest().authenticated()// 登录跳转 URL 无需认证
// 其他 url 需要身份认证;
.and().formLogin()
.loginPage("/test/login.html")// 登录跳转 URL
.loginProcessingUrl("/xdw/login")// 处理表单登录 URL
.usernameParameter("username1")
.passwordParameter("password1")
.successHandler(myAuthenticationSuccessHandler) //登录成功页面跳转的处理器
.failureHandler(myAuthenticationFailureHandler)//登录失败页面跳转的处理器
.and().csrf().disable(); //关闭跨站检测;
}
}
@Configuration
public class MyWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
/**
*
* addResourceHandlers 静态资源配置方法
* 1.效果和yml static-path-pattern 配置一致
* 2.</test/**>为key 会覆盖static-path-pattern 相同的内容
*
* @param registry
*/
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/test/**")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/templates/")
.addResourceLocations("classpath:/public/")
.addResourceLocations("classpath:/test/");
super.addResourceHandlers(registry);
}
}
/**
* 登入成功后跳转页面
*/
@Component
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler {
Logger logger = LoggerFactory.getLogger(MyAuthenticationSuccessHandler.class);
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
logger.info("MyAuthenticationSuccessHandler->登入成功");
redirectStrategy.sendRedirect(request, response, "/index");
}
}
/**
* 登入失败跳转页面
*/
@Component
public class MyAuthenticationFailureHandler implements AuthenticationFailureHandler {
Logger logger = LoggerFactory.getLogger(MyAuthenticationFailureHandler.class);
@Autowired
private ObjectMapper mapper;
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
logger.info("MyAuthenticationFailureHandler->登入失败");
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(mapper.writeValueAsString(exception.getMessage()));
}
}
@Configuration
public class CustomUserDetailsService implements UserDetailsService {
Logger logger = LoggerFactory.getLogger(CustomUserDetailsService.class);
@Autowired
private PasswordEncoder passwordEncoder;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
logger.info("CustomUserDetailsService->登入验证");
// 模拟一个用户,替代数据库获取逻辑
MyUser user = new MyUser();
user.setUserName(username);
user.setPassword(this.passwordEncoder.encode("123456"));
// 输出加密后的密码
System.out.println(user.getPassword());
return new User(username, user.getPassword(), user.isEnabled(),
user.isAccountNonExpired(), user.isCredentialsNonExpired(),
user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
}
}
public class MyUser implements Serializable {
private static final long serialVersionUID = 3497935890426858541L;
private String userName;
private String password;
private boolean accountNonExpired = true;
private boolean accountNonLocked= true;
private boolean credentialsNonExpired= true;
private boolean enabled= true;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isAccountNonExpired() {
return accountNonExpired;
}
public void setAccountNonExpired(boolean accountNonExpired) {
this.accountNonExpired = accountNonExpired;
}
public boolean isAccountNonLocked() {
return accountNonLocked;
}
public void setAccountNonLocked(boolean accountNonLocked) {
this.accountNonLocked = accountNonLocked;
}
public boolean isCredentialsNonExpired() {
return credentialsNonExpired;
}
public void setCredentialsNonExpired(boolean credentialsNonExpired) {
this.credentialsNonExpired = credentialsNonExpired;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
@RestController
public class LoginController {
Logger logger = LoggerFactory.getLogger(LoginController.class);
@GetMapping("hello")
public String hello() {
return "hello spring security";
}
@GetMapping("index")
public Object index(Authentication authentication) {
// return SecurityContextHolder.getContext().getAuthentication();
return authentication;
}
}
第三步:配置文件
server:
port: 9999
servlet:
context-path: /xdw
spring:
banner:
charset: utf-8
第四步:前台页面
前台代码太多了 ,你们自己去随便找一个就行了
<div class="materialContainer">
<div class="box">
<div class="title">江南一点雨-登录</div>
<form action="/xdw/xdw/login" method="post">
<div class="input">
<label for="username1">用户名</label>
<input type="text" name="username1" id="username1">
<span class="spin"></span>
</div>
<div class="input">
<label for="password1">密码</label>
<input type="password" name="password1" id="password1">
<span class="spin"></span>
</div>
<div class="button login">
<button type="submit">
<span>登录</span>
<i class="fa fa-check"></i>
</button>
</div>
</form>
<a href="javascript:" class="pass-forgot">忘记密码?</a>
</div>
以上配置完成就能通过自己页面去访问了
问题 配置 /xdw/login一致和/login 都存在问题
在官方文档上可以看到
配置文件中:
.loginProcessingUrl("/xdw/login")// 处理表单登录 URL
HTML中
<form action="/xdw/xdw/login" method="post">
这个两个地址应该都是
/login 就可以了
可是我这边配置项目路径,
servlet:
context-path: /xdw
如果和官方一致的话导致无法访问,后来了变相的方式处理,就是我上面的配置的方式,我简单查了一下可能是 重定向导致一些问题,具体源码没有仔细研究,有研究的可以告诉一下