Spring Boot的shiro整合(中)
阿新 • • 發佈:2018-11-09
一 配置
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);
}
}