shiro+spring相關配置


首先pom中添加所需jar包:

    <!-- shiro start -->
    <dependency>
        <groupId>org.apache.shiro</groupId>
        <artifactId>shiro-spring</artifactId>
        <version>1.2.3</version>
    </dependency>
    <!-- shiro end -->

 

一、在web.xml配制shiroFilter

    <!-- 配置Shiro過濾器,先讓Shiro過濾系統接收到的請求 -->  
    <!-- 這里filter-name必須對應applicationContext.xml中定義的<bean id="shiroFilter"/> -->  
    <!-- 使用[/*]匹配所有請求,保證所有的可控請求都經過Shiro的過濾 -->  
    <!-- 通常會將此filter-mapping放置到最前面(即其他filter-mapping前面),以保證它是過濾器鏈中第一個起作用的 -->  
     <filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
        <!-- 該值缺省為false,表示生命周期由SpringApplicationContext管理,設置為true則表示由ServletContainer管理   -->
        <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>

二、java代碼編寫

1.User.java

package isa.blog.bin.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class User implements Serializable {
    private static final long serialVersionUID = -5312120825533005238L;
    
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid",strategy="uuid")
    private String id;
    
    @Column(unique = true)
    private String userName;
    
    private String password;
    
    private Date createTime;
    
    private String email;
    
    @ManyToOne
    @JoinColumn
    private Role role;

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    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;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
    
}

 

2.Role.java

package isa.blog.bin.model;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class Role implements Serializable {
    private static final long serialVersionUID = -3431097890965814550L;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid",strategy="uuid")
    private String id;
    
    private String roleName;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }
    
}

 

3.Permission.java

package isa.blog.bin.model;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.GenericGenerator;

@Entity
public class Permission implements Serializable {
    private static final long serialVersionUID = 7808624074545962407L;

    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name="system-uuid",strategy="uuid")
    private String id;
    
    private String permissionName;
    
    @ManyToOne
    @JoinColumn
    private Role role;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPermissionName() {
        return permissionName;
    }

    public void setPermissionName(String permissionName) {
        this.permissionName = permissionName;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

 

4.UserDao.java

package isa.blog.bin.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import isa.blog.bin.model.User;

public interface UserDao extends JpaRepository<User, String> {
    User findByUserNameAndPassword(String userName, String password);
    User findOneByUserName(String userName);
}

 

5.PermissionDao.java

package isa.blog.bin.dao;

import java.util.Set;

import org.springframework.data.jpa.repository.JpaRepository;

import isa.blog.bin.model.Permission;
import isa.blog.bin.model.Role;

public interface PermissionDao extends JpaRepository<Permission, String> {
    Set<Permission> findByRole(Role role);
}

 

6.MyRealm.java

package isa.blog.bin.commons;

import java.util.HashSet;
import java.util.Set;

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.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import isa.blog.bin.dao.PermissionDao;
import isa.blog.bin.dao.UserDao;
import isa.blog.bin.model.Permission;
import isa.blog.bin.model.User;

@Transactional
public class MyRealm extends AuthorizingRealm{
    @Autowired
    private UserDao userDao;
    @Autowired
    private PermissionDao permissionDao;
    
    /**
     * 為當前登錄的用戶授予角色和權限
     */
    @Override
    public AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String userName = (String)principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        try{
            authorizationInfo.addRole(userDao.findOneByUserName(userName).getRole().getRoleName());
            Set<Permission> permissions = permissionDao.findByRole(userDao.findOneByUserName(userName).getRole());
            Set<String> strs = new HashSet<String>();
            for (Permission permission : permissions) {
                strs.add(permission.getPermissionName());
            }
            authorizationInfo.addStringPermissions(strs);
        }catch(Exception e){
            e.printStackTrace();
        }
        return authorizationInfo;
    }

    /**
     * 驗證當前登錄的用戶
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String userName = (String)token.getPrincipal();
        User user = userDao.findOneByUserName(userName);
        if(user!=null){
            AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(),"xx");
            return authcInfo;
        }else{
            return null;
        }
    }

}

三、配置文件applicationContext-shiro.xml

注意web.xml引入形式為:

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:/applicationContext*.xml</param-value>
    </context-param>

applicationContext-shiro.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- 緩存管理器 -->
    <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager"/>
    
    <!-- 繼承自AuthorizingRealm的自定義Realm,即指定Shiro驗證用戶登錄的類為自定義的ShiroDbRealm.java -->  
    <bean id="myRealm" class="isa.blog.bin.commons.MyRealm"/>  
    <!-- 踢出用戶 -->
    <bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO" />
    <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionDAO" ref="sessionDAO" />
    </bean>  
    <!-- Shiro默認會使用Servlet容器的Session,可通過sessionMode屬性來指定使用Shiro原生Session -->  
    <!-- 即<property name="sessionMode" value="native"/>,詳細說明見官方文檔 -->  
    <!-- 這里主要是設置自定義的單Realm應用,若有多個Realm,可使用'realms'屬性代替 -->  
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">  
        <property name="realm" ref="myRealm"/>
        <property name="sessionManager" ref="sessionManager" />
        <!-- 使用下面配置的緩存管理器 --> 
        <property name="cacheManager" ref="cacheManager"/> 
    </bean>  
      
    <!-- Shiro主過濾器本身功能十分強大,其強大之處就在於它支持任何基於URL路徑表達式的、自定義的過濾器的執行 -->  
    <!-- Web應用中,Shiro可控制的Web請求必須經過Shiro主過濾器的攔截,Shiro對基於Spring的Web應用提供了完美的支持 -->  
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">  
        <!-- Shiro的核心安全接口,這個屬性是必須的 -->  
        <property name="securityManager" ref="securityManager"/>  
        <!-- 要求登錄時的鏈接(可根據項目的URL進行替換),非必須的屬性,默認會自動尋找Web工程根目錄下的"/login.jsp"頁面 -->  
        <property name="loginUrl" value="/views/login.html"/> 
        <!-- 登錄成功后要跳轉的連接(本例中此屬性用不到,因為登錄成功后的處理邏輯在LoginController里硬編碼為main.jsp了) -->  
        <!-- <property name="successUrl" value="/index.html"/> --> 
        <!-- 用戶訪問未對其授權的資源時,所顯示的連接 -->  
        <!-- 若想更明顯的測試此屬性可以修改它的值,如unauthor.jsp,然后用[玄玉]登錄后訪問/admin/listUser.jsp就看見瀏覽器會顯示unauthor.jsp -->  
        <property name="unauthorizedUrl" value="/unauthorized.html"/>
        <!-- Shiro連接約束配置,即過濾鏈的定義 -->  
        <!-- 此處可配合我的這篇文章來理解各個過濾連的作用http://blog.csdn.net/jadyer/article/details/12172839 -->  
        <!-- 下面value值的第一個'/'代表的路徑是相對於HttpServletRequest.getContextPath()的值來的 -->  
        <!-- anon:它對應的過濾器里面是空的,什么都沒做,這里.do和.jsp后面的*表示參數,比方說login.jsp?main這種 -->  
        <!-- authc:該過濾器下的頁面必須驗證后才能訪問,它是Shiro內置的一個攔截器org.apache.shiro.web.filter.authc.FormAuthenticationFilter -->  
        <property name="filterChainDefinitions">  
            <value>  
                 /frame/user/login/** = anon
                 /frame/user/register/** = anon
                 /frame/kaptcha** = anon
                 
                 /css/**  = anon
                 /img/**  = anon
                 /js/**  = anon
                 /json/**  = anon
                 /Scripts/**  = anon 

                 /views/login.html  = anon
                 /views/register.html  = anon
                 
                 # /frame/essay = roles[member]
                 # /views/addBlog.html = roles[admin]
                 # /frame/deleteEssay/** = perms[刪除博客]
                 # /frame/deleteEssay/** = roles[admin]
                 
                 # 必須放在最后
                 /** = authc
            </value>  
        </property>
    </bean>  
      
    <!-- 保證實現了Shiro內部lifecycle函數的bean執行 -->  
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>  
      
    <!-- 開啟Shiro的注解(如@RequiresRoles,@RequiresPermissions),需借助SpringAOP掃描使用Shiro注解的類,並在必要時進行安全邏輯驗證 -->  
    <!-- 配置以下兩個bean即可實現此功能 -->  
    <!-- Enable Shiro Annotations for Spring-configured beans. Only run after the lifecycleBeanProcessor has run -->  
    <!-- 由於本例中並未使用Shiro注解,故注釋掉這兩個bean(個人覺得將權限通過注解的方式硬編碼在程序中,查看起來不是很方便,沒必要使用) -->  
    <!--   
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"/>  
      <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">  
        <property name="securityManager" ref="securityManager"/>  
      </bean>  
    -->

</beans>

 

以下代碼根據實際項目更改

UserController.java

package isa.blog.bin.controller;

import java.awt.image.BufferedImage;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
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 com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;

import isa.blog.bin.commons.JsonUtil;
import isa.blog.bin.commons.Result;
import isa.blog.bin.dto.UserDto;
import isa.blog.bin.service.UserService;

@RestController
@RequestMapping(value="/frame")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private Producer producer;
    
    private Map<String, String> map; 
    
    @RequestMapping(value="/user/register/{kaptchaCode}", method=RequestMethod.POST, produces=JsonUtil.JSON)
    public Result register(@RequestBody UserDto userDto, @PathVariable String kaptchaCode) {
        return userService.register(userDto, map, kaptchaCode);
    }
    
    @RequestMapping(value="/user/oneUser/{userId}", method=RequestMethod.GET, produces=JsonUtil.JSON)
    public Result getOneUser(@PathVariable String userId) {
        return userService.getOneUser(userId);
    }
    
    @RequestMapping(value="/user/login/{userName}/{password}/{kaptchaCode}", method=RequestMethod.GET, produces=JsonUtil.JSON)
    public Result login(@PathVariable String userName, @PathVariable String password, @PathVariable String kaptchaCode) throws UnsupportedEncodingException {
        return userService.login(URLDecoder.decode(userName, "UTF-8"), password, map, kaptchaCode);
    }
    
    @RequestMapping(value="/user/logout", method=RequestMethod.GET, produces=JsonUtil.JSON)
    public void logout() {
        userService.logout();
    }
    
    @RequestMapping(value="/user/userDetails_userName", method=RequestMethod.GET, produces=JsonUtil.JSON)
    public Result getOneUserName() {
        return userService.getOneUserName();
    }
    
    @RequestMapping(value="/user/userDetails", method=RequestMethod.GET, produces=JsonUtil.JSON)
    public Result getOneUserDetails() {
        String userId = userService.currentUserId();
        return userService.getOneUser(userId);
    }
    
    @RequestMapping(value="/user/updateUserDetails", method=RequestMethod.POST, produces=JsonUtil.JSON)
    public Result updateUserDetails(@RequestBody UserDto userDto) {
        String userId = userService.currentUserId();
        return userService.updateUserDetails(userId, userDto);
    }
    
    @RequestMapping("/kaptcha")
    public void initCaptcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");
        String capText = producer.createText();
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        BufferedImage bi = producer.createImage(capText);
        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            String kaptchaCode = (String)session.getAttribute(Constants.KAPTCHA_SESSION_KEY);
            map = new HashMap<String, String>();
            map.put("kaptchaCode", kaptchaCode);
            out.close();
        }
    }
    
    
}

 

UserService.java

package isa.blog.bin.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import isa.blog.bin.commons.MD5Util;
import isa.blog.bin.commons.Result;
import isa.blog.bin.dao.UserDao;
import isa.blog.bin.dto.UserDto;
import isa.blog.bin.model.User;

@Service
@Transactional
public class UserService {
    ModelMapper modelMapper = new ModelMapper();
    @Autowired
    private UserDao userDao;
    @Autowired
    private SessionDAO sessionDAO;
    
    /**
     * 注冊
     * @param userDto
     * @param map
     * @param kaptchaCode
     * @return
     */
    public Result register(UserDto userDto, Map<String, String> map, String kaptchaCode) {
        Result result = new Result();
        if (!map.get("kaptchaCode").equals(kaptchaCode)) {
            result.setSuccess(false);
            result.setMessage("驗證碼錯誤");
            return result;
        }
        User user = userDao.findOneByUserName(userDto.getUserName());
        if (user != null) {
            result.setSuccess(false);
            result.setMessage("用戶名已存在");
            return result;
        }
        user = modelMapper.map(userDto, User.class);
        user.setPassword(MD5Util.MD5(userDto.getPassword()));
        user.setCreateTime(new Date());
        userDao.save(user);
        result.setId(user.getId());
        result.setSuccess(true);
        result.setMessage("注冊成功");
        return result;
    }
    
    /**
     * 獲取一個用戶詳情
     * @param userId
     * @return
     */
    public Result getOneUser(String userId) {
        Result result = new Result(); 
        User user = userDao.findOne(userId);
        UserDto userDto = modelMapper.map(user, UserDto.class);
        List<UserDto> datas = new ArrayList<UserDto>(); 
        datas.add(userDto);
        result.setSuccess(true);
        result.setDatas(datas);
        return result;
    }
    
    /**
     * 登錄
     * @param userName
     * @param password
     * @param map
     * @param kaptchaCode
     * @return
     */
    public Result login(String userName, String password, Map<String, String> map, String kaptchaCode) {
        Result result = new Result();
        if (!map.get("kaptchaCode").equals(kaptchaCode)) {
            result.setSuccess(false);
            result.setMessage("驗證碼錯誤");
            return result;
        }
        
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userName, MD5Util.MD5(password));
        //踢除用戶
        this.kickOutUser(token);
        try{
            subject.login(token);
            Session session = subject.getSession();
            System.out.println("sessionId:"+session.getId());
            System.out.println("sessionHost:"+session.getHost());
            System.out.println("sessionTimeout:"+session.getTimeout());
            result.setMessage("登錄成功");
            System.out.println(userName+"登錄成功");
            List<UserDto> userDtos = new ArrayList<UserDto>();
            User user = this.userDao.findOneByUserName(userName);
            userDtos.add(modelMapper.map(user, UserDto.class));
            result.setDatas(userDtos);
            result.setSuccess(true);
            return result;
        }catch(Exception e){
            e.printStackTrace();
            result.setSuccess(false);
            result.setMessage("用戶名或密碼錯誤!");
            System.out.println("用戶名或密碼錯誤!");
            return result;
        }
        
    }
    
    /**
     * 獲得當前用戶id
     * @return
     */
    public String currentUserId() {
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection collection = subject.getPrincipals();
        if (null != collection && !collection.isEmpty()) {
            String userName = (String) collection.iterator().next();
            return userDao.findOneByUserName(userName).getId();
        }
        return null;
    }
    
    /**
     * 踢除用戶
     * http://www.ithao123.cn/content-7174367.html
     */
    public void kickOutUser(UsernamePasswordToken token){
        String loginName = token.getUsername();
        Collection<Session> sessions = sessionDAO.getActiveSessions();
        for(Session session:sessions){
            if(loginName.equals(String.valueOf(session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY)))) {
                //設置session立即失效,即將其踢出系統
                session.setTimeout(0);
            }
        }
    }
    
    /**
     * 退出登錄
     */
    public void logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            // session 會銷毀,在SessionListener監聽session銷毀,清理權限緩存
            subject.logout();
        }
    }
    
    /**
     * 獲取當前用戶名
     * @return
     */
    public Result getOneUserName() {
        Subject subject = SecurityUtils.getSubject();
        PrincipalCollection collection = subject.getPrincipals();
        Result result = new Result();
        if (null != collection && !collection.isEmpty()) {
            String userName = (String) collection.iterator().next();
            result.setSuccess(true);
            List<String> datas = new ArrayList<String>();
            datas.add(userName);
            result.setDatas(datas);
            return result;
        }
        result.setSuccess(false);
        return result;
    }
    
    /**
     * 修改用戶信息
     * @param userId
     * @param userDto
     * @return
     */
    public Result updateUserDetails(String userId, UserDto userDto) {
        Result result = new Result();
        User user = modelMapper.map(userDto, User.class);
        user.setId(userId);
        user.setPassword(userDao.findOne(userId).getPassword());
        user.setCreateTime(userDao.findOne(userId).getCreateTime());
        user.setRole(userDao.findOne(userId).getRole());
        if (!userDto.getUserName().equals(userDao.findOne(userId).getUserName())) {
            result.setMessage("修改成功,立即重新登錄!");
        } else {
            result.setMessage("修改成功!");
        }
        userDao.save(user);
        result.setId(userId);
        result.setSuccess(true);
        return result;
    }
    
}

需要注意,前端需要編寫全局ajax以便對用戶友好提示權限相關信息,

統一處理頁面登錄超時和無權限情況(一般在每一個頁面都會調用的js文件中編寫以便覆蓋完整)

    //統一處理頁面登錄超時和無權限情況
    jQuery(function($){  
        // 備份jquery的ajax方法    
        var _ajax = $.ajax;
        // 重寫ajax方法
        $.ajax=function(opt){ 
            var _error = opt && opt.error || function(a, b){};  
            var _opt = $.extend(opt, {  
                error:function(data, textStatus){  
                    // 如果后台將請求重定向到了登錄頁,則data里面存放的就是登錄頁的源碼,這里需要找到data是登錄頁的證據(標記)  
                    if(data.responseText.indexOf("無此權限") > 0) {  
                        alert("無此權限");
                        return;
                    }  else if (data.responseText.indexOf("請輸入用戶名") > 0) {
                        alert("登錄超時,請重新登錄!");
                        window.location.href = '/views/login.html';
                        return;
                    } else {
                        alert("error");
                        return;
                    }
                    _error(data, textStatus);
                }
            });
            _ajax(_opt);  
        };  
    });
data.responseText獲取得到的是applicationContext-shiro.xml里的配置
登錄超時:
<property name="loginUrl" value="/views/login.html"/>
無權限:
<property name="unauthorizedUrl" value="/unauthorized.html"/>
對應頁面的html的代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM