shiro-springmvc-mybatis登入認證 許可權控制
阿新 • • 發佈:2019-01-02
最近閒的沒事研究了一下shiro,整合springmvc-mybatis-maven做了一個簡單的登入認證許可權控制:
1:shiro jar
2:shiro 配置檔案:<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-cas</artifactId> <version>1.2.3</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-quartz</artifactId> <version>1.2.3</version> </dependency>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd"> <description>Shiro Configuration</description> <!-- Shiro's main business-tier object for web-enabled applications --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroDbRealm" /> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- 專案自定義的Realm認證登入 授權 --> <bean id="shiroDbRealm" class="com.cat.shiro.ShiroRealm"> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager" /> <property name="successUrl" value="/govern/pages/member/index" /> <property name="loginUrl" value="/govern/pages/login" /> <property name="unauthorizedUrl" value="/govern/pages/err" /> <!-- <property name="filters"> <map> <entry key="authc" value-ref="shiro"></entry> </map> </property> --> <property name="filterChainDefinitions"> <value> <!-- 靜態資源允許訪問 --> <!-- anon 允許訪問 --> /login/logincs.do = anon /login/submitcs.do = anon <!-- authc需要授權 --> /** = authc </value> </property> </bean> <!-- <bean id="shiro" class="com.cat.shiro.ShiroFilter"> </bean> --> <!-- 使用者授權資訊Cache --> <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" /> <!-- 保證實現了Shiro內部lifecycle函式的bean執行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- AOP式方法級許可權檢查 --> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean> <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans>
3:web.xml 對應配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:conf/shiro.xml
</param-value>
</context-param>
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
4:springmvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 載入包中的controller 註解掃描包 -->
<context:component-scan base-package="com.hnust.controller">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<!--配置攔截器, 多個攔截器,順序執行 -->
<!-- 匹配的是url路徑 -->
<!-- <mvc:mapping path="/user/**" /> <mvc:mapping path="/test/**" /> -->
<!-- 當設定多個攔截器時,先按順序呼叫preHandle方法,然後逆序呼叫每個攔截器的postHandle和afterCompletion方法 -->
<!-- 測試shiro許可權控制 暫時去掉自帶的許可權控制 <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/*/*" /> <bean
class="com.hnust.interceptor.LoginInterceptor"></bean> </mvc:interceptor> </mvc:interceptors> -->
<!-- 靜態資源的訪問 -->
<!-- 檢視分解器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/govern/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 國際化的訊息資原始檔(本系統中主要用於顯示/錯誤訊息定製) -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<!-- 在web環境中一定要定位到classpath 否則預設到當前web應用下找 -->
<value>classpath:/messages</value>
</list>
</property>
<property name="useCodeAsDefaultMessage" value="false" />
<property name="defaultEncoding" value="UTF-8" />
<property name="cacheSeconds" value="60" />
</bean>
<!-- 避免IE在ajax請求時,返回json出現下載 -->
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- 上傳檔案的解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<property name="maxUploadSize" value="10485760000" />
<property name="maxInMemorySize" value="40960" />
</bean>
<!-- 支援Shiro對Controller的方法級AOP安全控制 begin -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
depends-on="lifecycleBeanPostProcessor">
<property name="proxyTargetClass" value="true" />
</bean>
<!-- 無許可權 控制後臺不報錯 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.apache.shiro.authz.UnauthorizedException">405</prop>
<prop key="java.lang.Throwable">405</prop>
</props>
</property>
</bean>
</beans>
5:spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd ">
<!-- 引入jdbc配置檔案 -->
<context:property-placeholder location="classpath:conf/jdbc.properties" />
<context:annotation-config />
<!-- 使用Annotation自動註冊Bean,解決事物失效問題:在主容器中不掃描@Controller註解,在SpringMvc中只掃描@Controller註解。 -->
<!-- 掃描service、dao元件 --> <!-- base-package 如果多個,用“,”分隔 -->
<context:component-scan base-package="com.hnust">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<!-- 分解配置 jdbc.properites -->
<!-- 資料來源c3p0 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- <property name="maxPoolSize" value="${c3p0.pool.size.max}" /> <property name="minPoolSize" value="${c3p0.pool.size.min}"
/> <property name="initialPoolSize" value="${c3p0.pool.size.ini}" /> <property name="acquireIncrement"
value="${c3p0.pool.size.increment}" /> -->
</bean>
<!-- sessionFactory 將spring和mybatis整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:conf/mybatis-config.xml" />
<property name="mapperLocations" value="classpath:mapper/*.xml" /> <!-- 載入mapper檔案 -->
</bean>
<!-- 注入工具類 -->
<bean id="baseDao" class="com.hnust.base.BaseDao">
<property name="sqlSessionFactory">
<ref bean="sqlSessionFactory" />
</property>
</bean>
<!-- 事務 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="find" read-only="true" />
<tx:method name="get" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.hnust.service.impl.*.*(..))" id="pointCut" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
</aop:config>
</beans>
6:上面說的是配置檔案下面貼一下 java程式碼:
當前貼出來的類對應 上面2 配置檔案
pojo類就不貼了 我這裡沒連資料 只是模擬的使用者登入 和手動新增的許可權
/**
*
*/
package com.cat.shiro;
import java.util.ArrayList;
import java.util.List;
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.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationException;
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 com.cat.spring.entity.Role;
import com.cat.spring.entity.User;
/**
*/
public class ShiroRealm extends AuthorizingRealm {
/*
* 授權
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
// 根據使用者配置使用者與許可權
if (principals == null) {
throw new AuthorizationException(
"PrincipalCollection method argument cannot be null.");
}
String name = (String) getAvailablePrincipal(principals);
List<String> roles = new ArrayList<String>();
// 簡單預設一個使用者與角色,實際專案應User user = userService.getByAccount(name);
// 根據使用者名稱查詢出使用者 判斷使用者資訊的有效性 然獲取使用者的角色許可權 授權
User user = new User("shiro", "123456");
if (user.getName().equals(name)) {
// 模擬三個角色
for (int x = 0; x < 3; x++) {
roles.add("user" + x);
}
} else {
throw new AuthorizationException();
}
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 增加角色
// 取出所有角色授權
info.addRoles(roles);
// 取出所有許可權授權
// info.addStringPermissions(permissions);
// 模擬擁有的許可權
info.addStringPermission("cp:updatecs,updatecs1");
return info;
}
/*
* 認證登入
*/
@SuppressWarnings("unused")
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken authcToken) throws AuthenticationException {
UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
// 簡單預設一個使用者,實際專案應User user =
// userService.getByAccount(token.getUsername());
User user = new User("shiro", "123456");
if (user == null) {
throw new AuthorizationException();
}
SimpleAuthenticationInfo info = null;
if (user.getName().equals(token.getUsername())) {
info = new SimpleAuthenticationInfo(user.getName(),
user.getPassword(), getName());
}
return info;
}
}
7:logincontroller
package com.hnust.controller;
@Controller
@RequestMapping(value = "/login")
public class LoginController {
/*****************測試shiro************************************/
@RequestMapping(value = "/logincs", method = RequestMethod.GET)
public String logincs() {
return "/pages/login";
}
@RequestMapping(value = "/submitcs", method = RequestMethod.POST)
public String submitcs(String username, String password) {
User user = new User("shiro", "123456");
try {
// 如果登陸成功
if (user.getName().equals(username)
&& user.getPassword().equals(password)) {
UsernamePasswordToken token = new UsernamePasswordToken(
user.getName(), user.getPassword().toString());
Subject subject = SecurityUtils.getSubject();
subject.login(token);
return "/pages/member/index";
} else {
return "/pages/login";
}
} catch (Exception e) {
e.printStackTrace();
return "/pages/login";
}
}
}
8:測試許可權類 對應上面6 類裡面設定的許可權訪問URL
package com.hnust.controller;
@Controller
@RequestMapping(value = "/cp")
public class CompanyController extends BaseController{
/**
* updatecs
*/
@RequiresPermissions("cp:updatecs")
@RequestMapping(value="/updatecs",method=RequestMethod.GET)
public String updatecs(){
System.err.println("成功1");
return "index";
}
/**
* updatecs
*/
@RequiresPermissions("cp:updatecs1")
@RequestMapping(value="/updatecs1",method=RequestMethod.GET)
public String updatecs1(){
System.err.println("成功2");
return "index";
}
/**
* updatecs 這個我沒用給當前使用者新增許可權 是會提示無許可權的
*/
@RequiresPermissions("cp:updatecs2")
@RequestMapping(value="/updatecs2",method=RequestMethod.GET)
public String updatecs2(){
// System.err.println("失敗");
return "index";
}
}
9:下面貼出 效果圖
登入不做許可權驗證:
登入成功:
下面開始進行許可權認證:
這是我當前角色有的許可權 所以去到了我指定的頁面
下面進行 沒有許可權的URL訪問:
好了這就完事了: 新手發帖大神勿噴