1,引入pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2,创建SecurityConfig
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsService();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService())
.passwordEncoder(new CustomPasswordEncoder());//设置加密 没做成功
}
@Override
//授权的规则
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/*")
.permitAll()
.antMatchers("/admin/*").hasRole("ADMIN")//admin下面的需要认证才能访问
.and()
.formLogin()
.loginPage("/toLogin")//自定义登录页面
.permitAll()
.and()
.logout()
.permitAll();
http.csrf().disable();//关闭csrf
}
}
3,controller配合设置登录页面
@RequestMapping("/toLogin")
public String toLogin(){
return "/admin/login";
}
4,需要实现从数据库获取用户名密码和role来判断登录
创建service实现UserDetailsService重写loadUserByUsername方法
loadUserByUsername就是获取登录对象的方法
import java.util.*;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserMapper userMapper;//注入mapper
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User userInfo = userMapper.queryByUsername(username);
//通过mapper由loadUserByUsername传过来的login页面的username去数据库进行查找
if (userInfo == null) {
throw new UsernameNotFoundException(username);
}
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
//authorities是一个集合 比如说admin可以访问admin和user这两个权限下的 他就需要同时拥有这个两个权限
authorities.add(new SimpleGrantedAuthority("ROLE_" + userInfo.getRole()));
//数据库存储的是admin 需要在前面加一个ROLE_
Role role = new Role(userInfo.getUsername(),userInfo.getPassword(),authorities);
//这里role创建过了一个对象 role需要实现UserDetails接口才可以被返回
logger.info(role.toString());
return role;
}
5,我的数据库存储的用户
我没有直接使用user实现UserDetails而是创建另外一个对象 role来实现UserDetails这个接口
6,5,Role对象
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class Role implements UserDetails {
private String username;
private String password;
private Collection<SimpleGrantedAuthority> authorities;
@Override
public String toString() {
return "Role{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", authorities=" + authorities +
'}';
}
public Role(String username, String password, Collection<SimpleGrantedAuthority> authorities) {
this.username = username;
this.password = password;
this.authorities = authorities;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
@Override
public String getPassword() {
return this.password;
}
@Override
public String getUsername() {
return this.username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
再加上一个login页面代码 以及回显错误信息的
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css">
<link rel="stylesheet" href="../../static/css/me.css">
</head>
<body>
<div class=" m-container-small m-padded-tb-massive ">
<div class="ui middle aligned center aligned grid">
<div class="column" style="width: 30%">
<h1 class="ui teal image header">
<div class="content">
登录
</div>
</h1>
<br/>
<span th:if="${param.error}" th:text="${session?.SPRING_SECURITY_LAST_EXCEPTION?.message}" class="help-block" style="color:red;"></span>
<form class="ui large form" th:action="@{/toLogin}" method="post">
<div class="ui stacked segment">
<div class="field">
<div class="ui left icon input">
<i class="user icon"></i>
<input type="text" name="username" placeholder="用户名">
</div>
</div>
<div class="field">
<div class="ui left icon input">
<i class="lock icon"></i>
<input type="password" name="password" placeholder="密码">
</div>
</div>
<button class="positive ui button" type="submit">登录</button>
</div>
<div class="ui error message"></div>
</form>
<div class="ui message">
新用户? <button onclick="show()" >注册</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.2/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script>
<script type="text/javascript">
function show() {
alert("别注册");
}
</script>
</body>
</html>
加密资料看不太懂 有懂哥麻烦指点一下 有