pom文件導入
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- shiro ehcache -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.0</version>
</dependency>
Shiro權(quán)限配置主類
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 描述:Shiro權(quán)限配置
*/
@Configuration
public class ShiroConfig {
/**
* ShiroFilterFactoryBean 處理攔截資源文件問題瞎饲。
* 注意:單獨一個ShiroFilterFactoryBean配置是或報錯的肛炮,以為在
* 初始化ShiroFilterFactoryBean的時候需要注入:SecurityManager
*
Filter Chain定義說明
1裸扶、一個URL可以配置多個Filter榨为,使用逗號分隔
2、當設置多個過濾器時献联,全部驗證通過劝篷,才視為通過
3、部分過濾器可指定參數(shù)通今,如perms粥谬,roles
*
*/
@Bean
public ShiroFilterFactoryBean shirFilter(@Qualifier("securityManager") SecurityManager manager){
System.out.println(" 。辫塌。漏策。。shirFilter臼氨。掺喻。。储矩。感耙。。 ");
ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
bean.setSecurityManager(manager);
// 配置登錄的url和登錄成功的url
// bean.setLoginUrl("/static/html/login.html");
// bean.setSuccessUrl("/home");
// 定義過濾器
Map<String, Filter> filterMap = new LinkedHashMap<>();
filterMap.put("authc", new ShiroLoginFilter());
filterMap.put("perms", new ShiroPermissionsFilter());
bean.setFilters(filterMap);
// 配置訪問權(quán)限
LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 配置不同的URL采用的驗證方式
// anon表示可以匿名訪問
filterChainDefinitionMap.put("/login", "anon");
filterChainDefinitionMap.put("/info", "authc,perms");// 表示需要認證才可以訪問
// filterChainDefinitionMap.put("/**", "authc,perms");// 表示需要認證才可以訪問
// filterChainDefinitionMap.put("/*.*", "authc,perms");
bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return bean;
}
// 配置核心安全事務管理器
@Bean(name = "securityManager")
public SecurityManager securityManager(@Qualifier("userRealm") UserRealm userRealm) {
System.err.println("--------------shiro已經(jīng)加載----------------");
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(userRealm);
// manager.setSessionManager(sessionManager);
// manager.setCacheManager();
return manager;
}
// 配置自定義的權(quán)限登錄器
@Bean(name = "userRealm")
public UserRealm userRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
UserRealm userRealm = new UserRealm();
userRealm.setCredentialsMatcher(matcher);
return userRealm;
}
// 配置自定義的密碼匹配比較器
@Bean(name = "credentialsMatcher")
public CredentialsMatcher credentialsMatcher() {
return new CredentialsMatcher();
}
}
密碼匹配
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
/**
*
* 描述:密碼匹配比較
*/
public class CredentialsMatcher extends SimpleCredentialsMatcher {
@Override
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
System.out.println("....密碼的比對....");
UsernamePasswordToken utoken = (UsernamePasswordToken) token;
// 獲得用戶輸入的密碼:(可以采用加鹽(salt)的方式去檢驗)
String inPassword = new String(utoken.getPassword());
// 獲得數(shù)據(jù)庫中的密碼
String dbPassword = (String) info.getCredentials();
// 進行密碼的比對
return this.equals(inPassword, dbPassword);
}
}
用戶
/**
* 描述:用戶
*/
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
登錄及授權(quán)
import org.apache.shiro.authc.*;
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 java.util.ArrayList;
import java.util.List;
/**
*
* 描述:登錄及授權(quán)
*/
public class UserRealm extends AuthorizingRealm {
// 認證.登錄 提供賬戶信息返回認證信息
/**
* 當調(diào)用如下代碼時會進入這個方法(一般是登錄頁面)
* Subject currentUser = SecurityUtils.getSubject();
* currentUser.login(token);
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
throws AuthenticationException {
UsernamePasswordToken utoken = (UsernamePasswordToken) authenticationToken; // 獲取用戶輸入的token
System.out.println(".....認證.登錄....");
//根據(jù)用戶名去數(shù)據(jù)庫查詢相關(guān)記錄持隧,并返回驗證
String username = utoken.getUsername();
//
User user = new User();
user.setUsername(username);
user.setPassword("123456");
if (user == null) {
return null;
}
return new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
}
// 授權(quán) 角色
// 提供用戶信息返回權(quán)限信息
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 獲取session中的用戶
User user = (User) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
System.out.println();
System.out.println(".....授權(quán)....");
System.out.println();
List<String> permissions = new ArrayList<>();
permissions.add("abc1");
permissions.add("abc2");
// Set<Role> roles = user.getRoles();
// for (Role role : roles) {
// Set<Module> modules = role.getModules();
// for (Module module : modules) {
// permissions.add(module.getCode());
// }
// }
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addStringPermissions(permissions); // 將權(quán)限放入shiro中.
return info;
}
}
判斷是否已經(jīng)登錄
import org.apache.shiro.web.servlet.AdviceFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* 判斷是否登錄的過濾器即硼,被Shiro組件調(diào)用使用
*/
public class ShiroLoginFilter extends AdviceFilter {
/**
* 在訪問controller前判斷是否登錄,返回json屡拨,不進行重定向只酥。
*
* @param request
* @param response
* @return true-通過驗證褥实,false-驗證失敗
* @throws Exception
*/
@Override
protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
User User = (User) httpServletRequest.getSession().getAttribute("user");
httpServletRequest.getSession().setMaxInactiveInterval(36000);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with");
PrintWriter printWriter = null;
if (null == User) {
try {
printWriter = response.getWriter();
printWriter.write("{\"errorCode\": \"未登錄\"}");
printWriter.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (printWriter != null) {
printWriter.close();
}
}
return false;
}
return true;
}
}
判斷是否有權(quán)限
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
/**
*
* 描述:驗證是否有權(quán)限的過濾器
*/
public class ShiroPermissionsFilter extends PermissionsAuthorizationFilter {
@Override
public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
// 記錄日志
Subject subject = this.getSubject(request, response);
/**獲取用戶信息,可以根據(jù)用戶信息查看有沒有對應模塊的權(quán)限*/
User user = (User) subject.getPrincipal();
//true有權(quán)限; false沒有權(quán)限
boolean isPermitted = false;
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
String code = httpServletRequest.getParameter("cmd");
//寫死一個權(quán)限作為測試
if(code.equals("100"))//如何cmd=100就有權(quán)限
isPermitted = true;
return isPermitted;
}
/**
* shiro認證perms資源失敗后回調(diào)方法
*
* @param servletRequest
* @param servletResponse
* @return
* @throws IOException
*/
@Override
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws IOException {
PrintWriter printWriter = null;
try {
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType("application/json");
printWriter = servletResponse.getWriter();
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
printWriter.write("{\"error\": \"沒有權(quán)限\"}");
printWriter.flush();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (printWriter != null) {
printWriter.close();
}
}
return false;
}
}
Controller
import com.szcentral.conf.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
* Created by cgz on 2018-04-08 14:11
* 描述:
*/
@RestController
public class SampleController {
@RequestMapping("/")
String home() {
return "Hello World!";
}
@RequestMapping("/info")
public Map getMap(){
Map map = new HashMap();
map.put("name", "chen");
map.put("age", "22");
map.put("tel", "13682452210");
return map;
}
@RequestMapping("/login")
public String login(HttpSession session,
HttpServletRequest request,
HttpServletResponse response){
System.out.println("...接收登錄Controller裂允。损离。。绝编。");
//添加用戶認證信息
Subject subject = SecurityUtils.getSubject();
String username = "chen";
String pwd = "123456";
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, pwd);
//進行驗證草冈,這里可以捕獲異常,然后返回對應信息
subject.login(usernamePasswordToken);
User user = (User) subject.getPrincipal();
session.setAttribute("user", user);
return "login";
}
}