版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengqiuming/article/details/83869221
一 配置
1 MyShiroRealm类
package com.wzq.shiro.config;
import javax.annotation.Resource;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import com.wzq.shiro.entity.SysPermission;
import com.wzq.shiro.entity.SysRole;
import com.wzq.shiro.entity.UserInfo;
import com.wzq.shiro.service.UserInfoService;
public class MyShiroRealm extends AuthorizingRealm {
@Resource
private UserInfoService userInfoService;
/**
* 权限配置
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
System.out.println("MyShiroRealm->doGetAuthorizationInfo");
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
UserInfo userInfo = (UserInfo) principals.getPrimaryPrincipal();
for (SysRole role : userInfo.getRoles()) {
authorizationInfo.addRole(role.getRole());
for (SysPermission p : role.getPermissions()) {
authorizationInfo.addStringPermission(p.getPermission());
}
}
return authorizationInfo;
}
/**
* 主要是用来进行身份认证的,也就是说验证用户输入的账号和密码是否正确。
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
System.out.println("MyShiroRealm->doGetAuthenticationInfo");
//用户名
String username = (String) token.getPrincipal();
System.out.println("username:" + username);
//获取用户信息
UserInfo userInfo = userInfoService.findByUsername(username);
if (userInfo == null) {
return null;
}
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(userInfo,
userInfo.getPassword(), ByteSource.Util.bytes(userInfo.getCredentialsSalt()),
getName());
return authenticationInfo;
}
}
2 ShiroConfig
package com.wzq.shiro.config;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
@Configuration
public class ShiroConfig {
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器 从上到下执行
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
//不被拦截
filterChainDefinitionMap.put("/static/**", "anon");
//配置退出 shiro已经帮我们实现退出的代码
filterChainDefinitionMap.put("/logout", "logout");
//需要权限验证
filterChainDefinitionMap.put("/**", "authc");
//登陆页面
shiroFilterFactoryBean.setLoginUrl("/login");
//登陆成功跳转页面
shiroFilterFactoryBean.setSuccessUrl("/index");
//未授权页面
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* 凭证匹配器((由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了)
* @return
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {
HashedCredentialsMatcher hashedCredentialsMather = new HashedCredentialsMatcher();
hashedCredentialsMather.setHashAlgorithmName("md5"); //散列算法:这里使用MD5算法;
hashedCredentialsMather.setHashIterations(1); //散列的次数,如果散列两次,相当于 md5(md5(""));
return hashedCredentialsMather;
}
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myShiroRealm());
return securityManager;
}
/**
* 开启shiro aop注解支持
* @param securityManager
* @return
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
@Bean(name="simpleMappingExceptionResolver")
public SimpleMappingExceptionResolver createSimpleMappingExceptionResolver() {
SimpleMappingExceptionResolver r = new SimpleMappingExceptionResolver();
Properties mappings = new Properties();
mappings.setProperty("DatabaseException", "databaseError");
mappings.setProperty("UnauthorizedException", "403");
r.setExceptionMappings(mappings);
r.setDefaultErrorView("error");
r.setExceptionAttribute("ex");
return r;
}
}
二 dao层
package com.wzq.shiro.dao;
import org.springframework.data.repository.CrudRepository;
import com.wzq.shiro.entity.UserInfo;
public interface UserInfoDao extends CrudRepository<UserInfo, Integer>{
public UserInfo findByUsername(String username);
}
三 实体类
1 SysPermission
package com.wzq.shiro.entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class SysPermission implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1708879712215410035L;
@Id
@GeneratedValue
private Integer id;
private String name;
@Column(columnDefinition = "enum('menu','button')")
private String resourceType;
private String url;
private String permission;
private Long parentId;
private String parentIds;
private Boolean available = Boolean.FALSE;
@ManyToMany
@JoinTable(name = "SysRolePermission", joinColumns = { @JoinColumn(name = "permissionId") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })
private List<SysRole> roles;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getResourceType() {
return resourceType;
}
public void setResourceType(String resourceType) {
this.resourceType = resourceType;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public String getParentIds() {
return parentIds;
}
public void setParentIds(String parentIds) {
this.parentIds = parentIds;
}
public Boolean getAvailable() {
return available;
}
public void setAvailable(Boolean available) {
this.available = available;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
public List<SysRole> getRoles() {
return roles;
}
public void setRoles(List<SysRole> roles) {
this.roles = roles;
}
}
2 SysRole
package com.wzq.shiro.entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class SysRole implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2662493471572546262L;
@Id
@GeneratedValue
private Integer id;
private String role;
private String description;
private Boolean available = Boolean.FALSE;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "SysRolePermission", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "permissionId") })
private List<SysPermission> permissions;
@ManyToMany
@JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "roleId") }, inverseJoinColumns = { @JoinColumn(name = "uid") })
private List<UserInfo> userInfos;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Boolean getAvailable() {
return available;
}
public void setAvailable(Boolean available) {
this.available = available;
}
public List<SysPermission> getPermissions() {
return permissions;
}
public void setPermissions(List<SysPermission> permissions) {
this.permissions = permissions;
}
public List<UserInfo> getUserInfos() {
return userInfos;
}
public void setUserInfos(List<UserInfo> userInfos) {
this.userInfos = userInfos;
}
}
3 UserInfo
package com.wzq.shiro.entity;
import java.io.Serializable;
import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
@Entity
public class UserInfo implements Serializable {
/**
*
*/
private static final long serialVersionUID = 2408336391165537166L;
@Id
@GeneratedValue
private Integer uid;
@Column(unique = true)
private String username;
private String name;
private String password;
private String salt;
private byte state;
@ManyToMany(fetch=FetchType.EAGER)
@JoinTable(name = "SysUserRole", joinColumns = { @JoinColumn(name = "uid") }, inverseJoinColumns = { @JoinColumn(name = "roleId") })
private List<SysRole> roles;
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSalt() {
return salt;
}
public void setSalt(String salt) {
this.salt = salt;
}
public byte getState() {
return state;
}
public void setState(byte state) {
this.state = state;
}
public List<SysRole> getRoles() {
return roles;
}
public void setRoles(List<SysRole> roles) {
this.roles = roles;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
/**
* 密码盐.
*
* @return
*/
public String getCredentialsSalt() {
//重新对盐重新进行了定义,用户名+salt,这样就更加不容易被破解
//return this.username + this.salt;
//为了测试方便,我们简单定义盐为Mark
String salt = "Mark";
return salt;
}
四 服务层
1 UserInfoService
package com.wzq.shiro.service;
import com.wzq.shiro.entity.UserInfo;
public interface UserInfoService {
public UserInfo findByUsername(String username);
}
2 UserInfoServiceImpl
package com.wzq.shiro.service.impl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.wzq.shiro.dao.UserInfoDao;
import com.wzq.shiro.entity.UserInfo;
import com.wzq.shiro.service.UserInfoService;
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Resource
private UserInfoDao dao;
public UserInfo findByUsername(String username) {
return dao.findByUsername(username);
}
}
五 web层
1 HomeController
package com.wzq.shiro.web;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping({"/","/index"})
public String index() {
return "/index";
}
@RequestMapping("/login")
public String login(HttpServletRequest request,Map<String,Object> map) {
System.out.println("HomeController->login");
String exception = (String)request.getAttribute("shiroLoginFailure");
System.out.println("exception="+exception);
String msg = "";
if(exception!=null) {
if(UnknownAccountException.class.getName().equals(exception)) {
msg = "UnknownAccountException->账号不存在";
} else if(IncorrectCredentialsException.class.getName().equals(exception)) {
msg = "IncorrectCredentialsException->密码不正确";
} else if("kaptchaValidateFailed".equals(exception)) {
msg = "验证码错误";
} else {
msg = " else ->"+exception;
}
}
map.put("msg", msg);
return "/login";
}
@RequestMapping("/403")
public String unauthorizedRole() {
System.out.println("HomeController->unauthorizedRole");
return "/403";
}
}
2 UserInfoController
package com.wzq.shiro.web;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserInfoController {
/**
* 用户查询.
* @return
*/
@RequestMapping("/userList")
@RequiresPermissions("userInfo:view")//权限管理;
public String userInfo(){
System.out.println("UserInfoController->userInfo");
return "userInfo";
}
/**
* 用户添加;
* @return
*/
@RequestMapping("/userAdd")
@RequiresPermissions("userInfo:add")//权限管理;
public String userInfoAdd(){
System.out.println("UserInfoController->userInfoAdd");
return "userInfoAdd";
}
/**
* 用户删除;
* @return
*/
@RequestMapping("/userDel")
@RequiresPermissions("userInfo:del")//权限管理;
public String userDel() throws Exception{
System.out.println("UserInfoController->userDel");
return "userInfoDel";
}
}
六 启动类
package com.wzq.shiro;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ShiroApplication {
public static void main(String[] args) {
SpringApplication.run(ShiroApplication.class, args);
}
}