目录
一、页面准备
为了测试方便,首先在项目中创建一个pages文件夹创建a.html、b.html、c.html几个页面
二、修改配置类
package com.by.config;
//import com.by.service.UserService;
import com.by.service.UserService;
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.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.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
/**
* spring security 核心配置
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)//开启权限注解支持
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Autowired
private PasswordEncoder passwordEncoder;
/**
* 配置认证信息的来源
* AuthenticationManagerBuilder认证管理器
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// 配置认证提供者
auth.userDetailsService(userService).passwordEncoder(passwordEncoder);//配置认证提供者
super.configure(auth);//密码
}
/**
* 配置web的安全(忽略的静态资源)
*
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
//web.ignoring().antMatchers("/pages/a.html","/pages/b.html");
//web.ignoring().antMatchers("/pages/**");
//指定login.html页面可以匿名访问
web.ignoring().antMatchers("/login.html");
}
/**
* 配置HTTP请求的安全(认证、授权、退出)
* HttpSecurity 用于构建一个安全过滤器链 SecurityFilterChain
*
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
// super.configure(http);
http.formLogin()
.loginPage("/login.html")// 默认页面
.loginProcessingUrl("/login")//请求
.usernameParameter("username")//表单的username
.passwordParameter("password")//表单的password
// 请求成功后访问哪个路径,必须有true 要不然会有bug
.defaultSuccessUrl("/index.html",true);
//权限配置
http.authorizeRequests()
//.antMatchers("pages/a.html").authenticated()
.antMatchers("/pages/b.html").hasAuthority("add")
/**
* 拥有ROLE_ADMIN可以访问d页面
* 注意:此处虽然写的是ADMIN,但是框架会自动添加前缀ROLE_
*/
.antMatchers("pages/c.html").hasRole("ADMIN")
// 其他资源均需要登录后访问
.anyRequest().authenticated();
// super.configure(http);
//关闭跨站请求防护
http.csrf().disable();
}
/**
* 配置加密对象
* @return
*/
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
为方便测试。改造UserService
package com.by.service;
import com.by.pojo.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class UserService implements UserDetailsService {
@Autowired
private PasswordEncoder passwordEncoder;
//模拟向数据库中插入数据
public Map<String, UserInfo> map = new HashMap<>();
public void init() {
UserInfo u1 = new UserInfo();
u1.setUsername("admin");
u1.setPassword(passwordEncoder.encode("123"));
UserInfo u2 = new UserInfo();
u2.setUsername("user");
u2.setPassword(passwordEncoder.encode("123"));
map.put(u1.getUsername(), u1);
map.put(u2.getUsername(), u2);
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
init();
System.out.println("username:" + username);
//模拟从数据库中查询用户
UserInfo userInfo = map.get(username);
if (userInfo == null) {
return null;
}
//模拟查询数据库中用户的密码 去掉明文标识{noop}
String password = userInfo.getPassword();
List<GrantedAuthority> list = new ArrayList<>();
//授权,后期需要改为查询数据库动态获得用户拥有的权限和角色
if (username.equals("admin")) {
list.add(new SimpleGrantedAuthority("add"));
list.add(new SimpleGrantedAuthority("delete"));
}
list.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
User user = new User(username, password, list);
return user;
}
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
String password="123456";
/**
* BCryptPasswordEncoder是Spring Security
* 提供的一个加密的API
*/
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String hashPassWord = bCryptPasswordEncoder.encode(password);
System.out.println(hashPassWord);
boolean flag = bCryptPasswordEncoder.matches("123456", hashPassWord);
System.out.println(flag);
}
}
}
此时分别用admin用户和user用户登录测试效果。
三、测试
使用user用户名测试
登录成功后 访问a.html
接着访问b.html