Jar包依赖
<dependencies>
<!-- spring security import -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- spring thymeleaf import -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring web import -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
自定义认证配置
每套系统都有自己的业务逻辑配置,以下是我的业务逻辑配置
- 配置登录页为/login.html,登录成功后转入到index.html,登录错误转入error.html
- 如果出现越权访问则转入/refuse.html
- 登出成功后/index.html
- 除了能访问根目录,和index.html外其余的都需要安全校验
- securityUserDetailsService 为登录业务逻辑
package com.superxu.security.config;
import org.springframework.beans.factory.annotation.Autowired;
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.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import com.superxu.security.service.SecurityUserDetailsService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private SecurityUserDetailsService securityUserDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
/** 允许所有用户访问"/"和"/index.html */
.antMatchers("/", "/index.html").permitAll()
/** 其他地址的访问均需验证权限*/
.anyRequest().authenticated()
.and()
.formLogin()
/** 登录页 */
.loginPage("/login.html")
.defaultSuccessUrl("/index.html")
/** 转到错误页面 */
.failureUrl("/error.html").permitAll()
.and()
.rememberMe()
.and()
.exceptionHandling().accessDeniedPage("/refuse.html")
.and()
.logout()
/** 登出成功后转到index.html */
.logoutSuccessUrl("/index.html");
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityUserDetailsService);
}
}
配置用户登录逻辑
- 一般此处会查询数据库,获取用户信息
- 并读取用户对应权限,并绑定权限code
package com.superxu.security.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.superxu.security.entity.UserInfo;
import com.superxu.security.entity.UserPermission;
import com.superxu.security.service.SecurityUserDetailsService;
import com.superxu.security.service.UserService;
@Service
public class SecurityUserDetailsServiceImpl implements SecurityUserDetailsService {
@Autowired
private UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
UserInfo userInfo = userService.login(username);
/** 抛出异常 */
if (null == userInfo) {
throw new UsernameNotFoundException(username);
}
List<SimpleGrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
/**
* 获得用户权限
* */
List<UserPermission> permission = userInfo.getPermission();
for (UserPermission userPermission : permission) {
SimpleGrantedAuthority authority=new SimpleGrantedAuthority(userPermission.getCode());
authorities.add(authority);
}
return new User(userInfo.getUserName(), userInfo.getPassword(), authorities);
}
}
商品管理业务逻辑
package com.superxu.security.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/shop")
public class ShoppingController {
@PreAuthorize("hasAuthority('ShopList')")
@GetMapping("/list.html")
public String list() {
return "shop/list";
}
@PreAuthorize("hasAuthority('ShopAdd')")
@GetMapping("/add.html")
public String add() {
return "shop/add";
}
}
个人中心业务逻辑
package com.superxu.security.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
/**
* 个人中心
*/
@PreAuthorize("hasAuthority('UserIndex')")
@GetMapping("/index")
public String index() {
return "user/index";
}
}
登录业务逻辑
package com.superxu.security.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class LoginController {
@RequestMapping("/index.html")
public String index() {
return "index";
}
@RequestMapping("/login.html")
public String login() {
return "login";
}
@RequestMapping("/refuse.html")
public String refuse() {
return "refuse";
}
@RequestMapping("/error.html")
public String loginError(Model model) {
model.addAttribute("loginError", true);
System.out.println("error");
return "error";
}
}
网友评论