案例程序下載地址:https://github.com/snowlavenderlove/springsecurity.git
1.創建數據庫springsecurity,並創建三張表,sys_user,sys_role,sys_user_role,並插入記錄,圖如下:
2.創建項目springsecurityUserRole,創建時添加web、thymeleaf、jpa、security、mysql、mybatis框架,創建項目參考博文:https://blog.csdn.net/qq_37231511/article/details/90669242
3.在pom.xml中添加druid、logging依賴
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.17</version>
</dependency>
4.編輯application.properties
#mysql
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springsecurity
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
#druid
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#mybatis
mybatis.type-aliases-package=com.xue.repository.dao
mybatis.mapper-locations=classpath*:com/xue/repository/mapper/*.xml
5.通過mybatis-generator自動生成代碼,參考博文:https://blog.csdn.net/qq_37231511/article/details/90692784,自動生成後如圖:
6.創建service層,創建SysUserService、SysRoleService、SysUserRoleService,代碼如圖
SysUserService
package com.xue.service;
import com.xue.entity.model.SysUser;
public interface SysUserService {
public SysUser selectUserByName(String username);
public SysUser selectUserById(Integer id);
}
SysRoleService
package com.xue.service;
import com.xue.entity.model.SysRole;
public interface SysRoleService {
public SysRole selectRoleById(Integer id);
}
SysUserRoleService
package com.xue.service;
import java.util.List;
import com.xue.entity.model.SysUserRole;
public interface SysUserRoleService {
public List<SysUserRole> selectUserRoleByUserId(Integer userId);
}
7.創建Service層實現包:Impl,並創建SysUserServiceImpl、SysRoleServiceImpl、SysUserRoleServiceImpl,代碼如下:
SysUserServiceImpl
package com.xue.service.Impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xue.entity.model.SysUser;
import com.xue.repository.dao.SysUserMapper;
import com.xue.service.SysUserService;
@Service
public class SysUserServiceImpl implements SysUserService {
@Autowired
private SysUserMapper sysUserMapper;
@Override
public SysUser selectUserByName(String username) {
// TODO Auto-generated method stub
return sysUserMapper.selectUserByName(username);
}
@Override
public SysUser selectUserById(Integer id) {
// TODO Auto-generated method stub
return sysUserMapper.selectUserById(id);
}
}
SysRoleServiceImpl
package com.xue.service.Impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xue.entity.model.SysRole;
import com.xue.repository.dao.SysRoleMapper;
@Service
public class SysRoleServiceImpl implements com.xue.service.SysRoleService {
@Autowired
private SysRoleMapper sysRoleMapper;
@Override
public SysRole selectRoleById(Integer id) {
// TODO Auto-generated method stub
return sysRoleMapper.selectRoleById(id);
}
}
SysUserRoleServiceImpl
package com.xue.service.Impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xue.entity.model.SysUserRole;
import com.xue.repository.dao.SysUserRoleMapper;
import com.xue.service.SysUserRoleService;
@Service
public class SysUserRoleServiceImpl implements SysUserRoleService {
@Autowired
private SysUserRoleMapper sysUserRoleMapper;
@Override
public List<SysUserRole> selectUserRoleByUserId(Integer userId) {
// TODO Auto-generated method stub
return sysUserRoleMapper.selectUserRoleByUserId(userId);
}
}
8.編輯dao層,編輯SysUserMapper、SysRoleMapper、SysUserRoleMapper文件
SysUserMapper:在最後添加
SysUser selectUserByName(String username);
SysUser selectUserById(Integer id);
SysRoleMapper:在最後添加
SysRole selectRoleById(Integer id);
SysUserRoleMapper:在最後添加
List<SysUserRole> selectUserRoleByUserId(Integer userId);
9.編輯mapper,編輯SysUserMapper、SysRoleMapper、SysUserRoleMapper
SysUserMapper:在最後添加
<select id="selectUserById">
select * from sys_user where id = #{id}
</select>
SysRoleMapper:在最後添加
<select id="selectRoleById" resultMap="BaseResultMap">
select * from sys_role where id = #{id}
</select>
SysUserRoleMapper:在最後添加
<select id="selectUserRoleByUserId" resultMap="BaseResultMap">
select * from sys_user_role where user_id =#{userId}
</select>
10.在src/main/resources/templates下創建home.html與login.html
home.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>首頁</title>
</head>
<body>
<h1>登陸成功</h1>
<a href="/admin">擁有admin權限</a>
<a href="/user">擁有user權限</a>
<button onclick="window.location.href='/logout'">退出</button>
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Insert title here</title>
</head>
<body>
<h1 align="left">登陸</h1>
<form action="/login" method="post">
用戶名:<input type="text" name="username"/>
密碼:<input type="password" name="password" />
<button type="submit">登陸</button>
</form>
</body>
</html>
11.創建Controller層,創建類LoginSecurityController
package com.xue.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginSecurityController {
@RequestMapping("/")
public String index(){
return "home";
}
@RequestMapping("/login")
public String login(){
return "login";
}
/**
* @PreAuthorize作用:判斷用戶是否有指定權限,沒有就不能訪問
*/
@RequestMapping("/admin")
@ResponseBody
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String admin(){
return "此權限爲admin所有!";
}
@RequestMapping("/user")
@ResponseBody
@PreAuthorize("hasRole('ROLE_USER')")
public String user(){
return "此權限爲user所有!";
}
}
12.創建security層,創建CustomUserDetailsService,WebSecurityConfig
CustomUserDetailsService
package com.xue.security;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
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.stereotype.Service;
import com.xue.entity.model.SysRole;
import com.xue.entity.model.SysUser;
import com.xue.entity.model.SysUserRole;
import com.xue.service.SysRoleService;
import com.xue.service.SysUserRoleService;
import com.xue.service.SysUserService;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private SysUserService sysUserService;
@Autowired
private SysRoleService sysRoleService;
@Autowired
private SysUserRoleService sysUserRoleService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// TODO Auto-generated method stub
Collection<GrantedAuthority> authorities = new ArrayList<>();
//從數據庫user表中查詢登陸者用戶信息
SysUser user = sysUserService.selectUserByName(username);
if(null == user){
throw new UsernameNotFoundException("用戶不存在");
}
//從數據庫sys_user_role表中查詢登陸者所對應的用戶權限關聯信息
List<SysUserRole> userRoleList = sysUserRoleService.selectUserRoleByUserId(user.getId());
for(SysUserRole datas:userRoleList){
//根據用戶權限關聯信息表中的權限id,從數據庫sys_role表中查詢登陸者所對應權限
SysRole role = sysRoleService.selectRoleById(datas.getRoleId());
authorities.add(new SimpleGrantedAuthority(role.getName()));
}
return new User(user.getUsername(),user.getPassword(),authorities);
}
}
WebSecurityConfig
package com.xue.security;
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.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
// TODO Auto-generated method stub
/**
* 密碼的加密方式
*/
auth.userDetailsService(customUserDetailsService).passwordEncoder(new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return charSequence.toString();
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return s.equals(charSequence.toString());
}
});
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO Auto-generated method stub
/**
* .anyRequest().authenticated():設置所有請求都需通過認證才能訪問
* .and():表示一個配置的結束
* .formLogin().loginPage("/login"):設置登陸頁,loginPage中是對應controller中的登陸RequestMapping
* .defaultSuccessUrl("/").permitAll():設置登陸成功頁
*/
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().loginPage("/login")
.defaultSuccessUrl("/").permitAll()
.and()
.logout().permitAll();
/**
* 關閉csrf
*/
http.csrf().disable();
}
@Override
public void configure(WebSecurity web) throws Exception {
// TODO Auto-generated method stub
}
}
13.編輯主程序類SpringsecurityUserRoleApplication
package com.xue;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.xue.repository.dao")
public class SpringsecurityUserRoleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringsecurityUserRoleApplication.class, args);
}
}
14.綜上代碼結構如圖:
15.啓動程序,在瀏覽器輸入http://localhost:8080/login,用賬號a密碼123456登陸,登陸成功後如圖
16.點擊擁有admin權限文字鏈接,沒有權限則報錯403
17. 點擊擁有user權限文字鏈接,如圖擁有權限
18.用admin賬號登陸,則沒有user權限