关于ssm整合shiro框架

2020-03-31 16:05:54来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

菜鸟的第一次。不足之处多谅解

 

 

1,添加shiro配置文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util"
 6     xsi:schemaLocation="
 7         http://www.springframework.org/schema/beans 
 8         http://www.springframework.org/schema/beans/spring-beans.xsd
 9         http://www.springframework.org/schema/util
10         http://www.springframework.org/schema/util/spring-util.xsd
11         http://www.springframework.org/schema/aop 
12         http://www.springframework.org/schema/aop/spring-aop.xsd
13         http://www.springframework.org/schema/context
14         http://www.springframework.org/schema/context/spring-context.xsd
15         http://www.springframework.org/schema/tx
16         http://www.springframework.org/schema/tx/spring-tx.xsd
17         http://www.springframework.org/schema/p
18         http://www.springframework.org/schema/p/spring-p.xsd
19         ">
20         
21     <context:component-scan base-package="cn.ljs.realm"/>
22     <!-- 
23     1. 配置securityManager,也就是shiro的核心。
24      -->
25     <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
26         <property name="realm" ref="myRealm" />
27         <!-- 缓存管理器 -->
28         <property name="cacheManager" ref="cacheManager" />
29         <property name="sessionManager" ref="sessionManager"></property>
30 
31     </bean>
32     <!-- 
33     2. 配置cacheManager(缓存管理)
34      -->
35     <bean id="cacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager">
36     </bean>
37     <!-- 
38     3. 配置Realm,自己定义的shiroRealm,必须实现org.apache.shiro.realm.Realm这个接口
39      -->
40     <bean id="myRealm" class="cn.ljs.realm.MyRealm"></bean>
41     <!-- 
42     4.配置lifecycleBeanPostProcessor, 可以自动的来调用配置在spring IOC 容器中shiro bean的生命周期方法 -->
43     <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />
44     <!-- 
45     5.启用IOC容器中使用shiro的注解,但必须在配置 lifecycleBeanPostProcessor才可以使用-->
46     <bean
47         class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
48         depends-on="lifecycleBeanPostProcessor" />
49     <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
50         <property name="securityManager" ref="securityManager"/>
51     </bean>
52     
53     <!-- 存储登录用户的信息 -->
54     <bean id="sessionDao" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>
55     <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
56         <!-- 设置超时时间 -->
57         <property name="globalSessionTimeout" value="14400000"/>
58         <property name="sessionDAO" ref="sessionDao"/>
59     </bean>
60     <!-- 
61     6. 配置shiroFilter
62     6.1 id必须和web.xml 文件中配置的DelegatingFilterProxy的filter-name一致
63      -->
64     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
65         <property name="securityManager" ref="securityManager" />
66         <property name="loginUrl" value="/index.jsp" /><!-- 项目未登录访问,默认进入的页面, -->
67         <!-- <property name="successUrl" value="/user/list.do" />-->
68         <!-- <property name="unauthorizedUrl" value="/index.jsp" />  -->
69 
70         <!-- shiro的过滤器 - 过滤规则
71                                     常用的过滤器:
72             authc:必须认证才能通过
73             anon:游客可以通过
74             logout:注销的请求
75          -->
76         <property name="filterChainDefinitions">
77             <value>
78                <!-- 需要放行在这里配置,未放行的会被拦截,如下, -->
79                 /css/**=anon
80                 /images/**=anon
81                 /js/**=anon
82                 /**=authc   
83             </value>
84         </property>
85 
86     </bean>
87 </beans>

2,spring-mvc添加shiro配置

<!--Shiro配置-->
    <aop:config proxy-target-class="true"></aop:config>
    <bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
        <property name="securityManager" ref="securityManager" />
    </bean>

3,web.xml添加shiro过滤器

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1" metadata-complete="true">

    <!--Shiro过滤器-->
    <filter>
        <filter-name>shiroFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>transformWsdlLocations</param-name>
            <param-value>true</param-value>
        </init-param>
        <!-- &lt;!&ndash;在from文件上传springContext接收&ndash;&gt; -->
        <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>

    <!-- 加载spring容器配置 -->
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    <!-- 设置spring容器加载所有的配置文件路径 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:spring*.xml
        <!-- 配置文件名字统一就不用下面这个 --> classpath:applicationContext*.xml </param-value> </context-param> <context-param> <param-name/> <param-value/> </context-param> <!-- 配置springMVC核心控制器 --> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置初始配置化文件,前面contextConfigLocation看情况二选一 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring-mvc.xml </param-value> </init-param> <!-- 启动加载一次 --> <load-on-startup>1</load-on-startup> </servlet> <!--为DispatcherServlet建立映射 --> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 解决工程编码过滤器 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowGenericHttpRequests</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.allowOrigin</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowSubdomains</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, HEAD, POST, OPTIONS</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>X-Test-1, X-Test-2</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.maxAge</param-name> <param-value>3600</param-value> </init-param> </filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>

4,自定义一个 myRealm,名字要跟配置一样

 里面核心代码:用户认证核心逻辑看需要什么,这里只写大致逻辑

package cn.ljs.realm;

import org.apache.shiro.SecurityUtils;
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.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.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import cn.ljs.entity.SysResc;
import cn.ljs.entity.SysRole;
import cn.ljs.entity.SysUser;
import cn.ljs.service.SysUserLoginService;

import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;


/**
 * Shiro的数据源
 */

@Component
public class MyRealm extends AuthorizingRealm {/**
     * 权限控制 - 每次验证权限时都会调用
     * @param principals
     * @return
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser) principals.getPrimaryPrincipal();

        //从用户对象中直接获得权限列表
        //List<SysResc> rescs = user.getSysResc();

      String string = user.getSysRole().getRescs();
      SysResc sysResc = new SysResc();
      sysResc.setRquanxian(string);
      List<SysResc> rescs = new ArrayList<>();
      rescs.add(sysResc);


    
if(rescs != null || role!=null){ SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); for (SysResc resc : rescs) { if(resc.getRquanxian() != null && !"".equals(resc.getRquanxian())) { simpleAuthorizationInfo.addStringPermission(resc.getRquanxian()); } }
        //simpleAuthorizationInfo.addRole(rolename);//也可以根据需要存入角色名字,名字从user对象获取
return simpleAuthorizationInfo; } return null; } /** * 身份认证 * @param token * @return * @throws AuthenticationException */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        //获得登录时的用户名
        String username = (String) token.getPrincipal();
     SysUser user=new SysUser();

          //通过用户名查询用户信息
          List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
          Map<String, Object> map=new HashMap<String, Object>();
          list = userLogin.queryUser(username);


          for(int i=0;i<list.size();i++) {//数据就用了三张表,用户表,角色表,权限表,没有用中间表,权限表是一个字典表,
              map=list.get(i);
              //查出来的账号信息全部放入实体类就行,比如。

               user.setName((String)map.get("name"));//名字

         //角色信息

         SysRole role=new SysRole();

         //登录时一并查出来的角色信息放进去,就列举一个,需要什么放什么

              role.setRescs((String) map2.get("rescs"));//权限,这里存入的信息在后面会用到。比如上面的权限控制:doGetAuthorizationInfo

              user.setSysRole(role);

}

        if(user != null){//将用户认证信息存入shiro框架
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
            return simpleAuthenticationInfo;
        }else {

        }
        return null;
    }
}

5,登录方法调用,以及保证线上同一个账号只允许一个在线,其他的通通挤下线,

  有两个登录方法:

      1,第一个是做了登录次数限制,密码错误三次十分钟之内不可以再次尝试登录,如果密码输入错误总次数大于十次,账号会被锁定。需要在用户表增加三个字段,再根据项目做调整。

package cn.ljs.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.ljs.entity.ClientIP;
import cn.ljs.entity.Logtable;
import cn.ljs.entity.SysUser;
import cn.ljs.service.LogtableService;
import cn.ljs.service.SysUserLoginService;
import cn.ljs.util.Loggings;
import cn.ljs.util.MD5;
import cn.ljs.util.TimeUtil;

@Controller
@RequestMapping("/loginController")
public class LoginController {
    
    @Autowired
    private SysUserLoginService userLogin;
    //private UserManageService userservice;
    
    @Autowired
    private LogtableService logtableService;
    
     @RequestMapping("/login")
     @ResponseBody
    public List<String> login(String username, String password, Model model,HttpServletRequest request,
            HttpServletResponse response){
         List<String> list = new ArrayList<>();
         String ret="";
         String ip = request.getHeader("x-forwarded-for");  
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        //交给shiro进行认证
        Subject subject = SecurityUtils.getSubject();
        //对密码加密处理
        password = MD5.makeMD5(password);  
        //获得系统时间,与账号最后登录时间对比,密码错误超过3次禁用10分钟,超过10次锁定账号
        Date date = new Date();
        SimpleDateFormat sdf =   new SimpleDateFormat( " yyyy-MM-dd HH:mm:ss " );
        String nowTime = sdf.format(date);
        Date time = null;
        try {
            time = sdf.parse( nowTime );
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        //获取账号状态,判断是否已被锁定,statesum大于10则锁定,
        SysUser users=new SysUser();
        List<Map<String, Object>> userlist = new ArrayList<Map<String,Object>>();
        Map<String, Object> map=new HashMap<String, Object>();
        userlist = userLogin.queryUser(username);
        for(int i=0;i<userlist.size();i++) {
            map=userlist.get(i);
            users.setId((Integer) map.get("id"));
            users.setState((Integer) map.get("state"));
            users.setStatesum((Integer) map.get("statesum"));
            users.setLogintime((Date) map.get("logintime"));
        }
        Integer state2 = users.getState();
        Integer statesum2 = users.getStatesum();
        if(statesum2==null) {
            statesum2=0;
        }
        //state=3,logintime<10分钟为临时锁定,十分钟后才可以登录
        if(users.getLogintime()!=null && state2!=null) {
            //计算时间差(分钟)
            long datePoor = TimeUtil.getDatePoor(users.getLogintime());
            //时间超过十分钟后更新当前账号状态
            if (statesum2>9) {
                ret = "账号已被锁定,请联系管理员!";
                list.add(ret); 
                return list;
            }else if(state2>2 && datePoor<10) {
                ret = "账号已被锁定十分钟,请稍后重试!";
                list.add(ret); 
                return list;
            }else if(datePoor>10){
                users.setState(null);
                //锁定十分钟后,清空state次数
                userLogin.updateState(users);
            }
        }

        
        if(!subject.isAuthenticated()){

            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            try {
                subject.login(token);
             // 剔除其他此账号在其它地方登录
                List<Session> loginedList = getLoginedSession(subject);
                for (Session session : loginedList) {
                    session.stop();
                } 
            } catch (UnknownAccountException ex1) {
                ex1.printStackTrace();
                ret = "账号或密码错误,请重新输入!";
                list.add(ret);  
                return list;
            } catch (IncorrectCredentialsException ex2) { 
                ex2.printStackTrace();
                
                //重新查询账号状态
                SysUser u = new SysUser();
                List<Map<String, Object>> userlists = new ArrayList<Map<String,Object>>();
                Map<String, Object> maps=new HashMap<String, Object>();
                userlists = userLogin.queryUser(username);
                for(int i=0;i<userlists.size();i++) {
                    maps=userlists.get(i);
                    u.setId((Integer) maps.get("id"));
                    u.setState((Integer) maps.get("state"));
                    u.setStatesum((Integer) maps.get("statesum"));
                    u.setLogintime((Date) maps.get("logintime"));
                    u.setLasttime((Date) maps.get("lasttime"));
                }
                
                Integer state = u.getState();//错误次数
                Integer statesum = u.getStatesum();
                
                if(state==null && statesum==null) {
                    state=1;
                    u.setState(state);
                    u.setStatesum(state);
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号或密码错误,您还有"+(3-state)+"次输入机会!";
                    list.add(ret); 
                    return list;
                }else if(statesum>8) {
                    statesum=statesum+1;
                    state=3;
                    u.setStatesum(statesum);//
                    u.setState(state);
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号已被锁定,请联系管理员!";
                    list.add(ret); 
                    return list;
                }else if (state == null) {
                    state=1;
                    statesum=statesum+1;
                    u.setState(state);
                    u.setStatesum(statesum);
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号或密码错误,您还有"+(3-state)+"次输入机会!";
                    list.add(ret); 
                    return list;
                }else if (statesum == null) {
                    statesum=1;
                    u.setState(state);
                    u.setStatesum(state);
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号或密码错误,您还有"+(3-state)+"次输入机会!";
                    list.add(ret); 
                    return list;
                }else if(state<2) {
                    state=state+1;
                    statesum=statesum+1;
                    u.setState(state);//
                    u.setStatesum(statesum);//更新失败总次数
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号或密码错误,您还有"+(3-state)+"次输入机会!";
                    list.add(ret); 
                    return list;
                }else{
                    state=state+1;
                    statesum=statesum+1;
                    u.setState(state);
                    u.setStatesum(statesum);//
                    u.setLogintime(time);//登录失败,密码错误,当前登录时间
                    userLogin.updateState(u);
                    ret = "账号已被锁定十分钟,请稍后重试!";
                    list.add(ret); 
                    return list;
                }
            }catch (AuthenticationException ex3) {  
                ret = "账号或密码错误,请重新输入!";
                list.add(ret); 
                return list;
            }
        }

        Integer state = users.getState();
        Integer statesum = users.getStatesum();
        if(state!=null) {
            if(state>2) {
                ret = "账号已被锁定十分钟,请稍后重试!";
                list.add(ret); 
                return list;
            }else if ( statesum>9) {
                ret = "账号已被锁定,请联系管理员!";
                list.add(ret); 
                return list;
            }else {
                ret="登录成功";
                list.add(ret);
            }
        }else {
            ret="登录成功";
            list.add(ret);
        }
        //获得当前认证的对象
        SysUser user = (SysUser) subject.getPrincipal();
        user.setState(null);
        user.setStatesum(null);
        user.setLogintime(null);
        user.setLasttime(time);
        user.setLastip(ip);
        userLogin.updateState(user);
        
        //将权限存入session,页面通过Ajax调用存入session的权限
        HttpSession session = request.getSession();
        String rolename = user.getSysRole().getRolename();
        if(!session.equals("")||session!=null) {
            session.setAttribute("user", user.getSysResc());
            session.setAttribute("id", user.getId());
            session.setAttribute("role", user.getRoles());
            session.setAttribute("account", user.getAccount());
            session.setAttribute("password", user.getPassword());
            session.setAttribute("name", user.getName());
            session.setAttribute("rolename", rolename);
        }
return list;
    }
     

    //遍历同一个账户的session
    private List<Session> getLoginedSession(Subject currentUser) {
        Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils
                .getSecurityManager()).getSessionManager()).getSessionDAO()
                .getActiveSessions();
        List<Session> loginedList = new ArrayList<Session>();
        SysUser loginUser = (SysUser) currentUser.getPrincipal();
        for (Session session : list) {
            Subject s = new Subject.Builder().session(session).buildSubject();
            if (s.isAuthenticated()) {
                SysUser user = (SysUser) s.getPrincipal();
                if (user.getId()==(loginUser.getId())) {
                    if (!session.getId().equals(currentUser.getSession().getId())) {
                        loginedList.add(session);
                    }
                }
            }
        }
        return loginedList;
    }

}

2,第二个没有限制,只要认证成功就可以。

package cn.ljs.controller;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.ljs.entity.ClientIP;
import cn.ljs.entity.Logtable;
import cn.ljs.entity.SysUser;
import cn.ljs.service.LogtableService;
import cn.ljs.service.SysUserLoginService;
import cn.ljs.util.Loggings;
import cn.ljs.util.MD5;
import cn.ljs.util.TimeUtil;

@Controller
@RequestMapping("/loginController")
public class LoginController {
    
    @Autowired
    private SysUserLoginService userLogin;
    //private UserManageService userservice;
    
    @Autowired
    private LogtableService logtableService;
    
     @RequestMapping("/login")
     @ResponseBody
    public List<String> login(String username, String password, Model model,HttpServletRequest request,
            HttpServletResponse response){
         List<String> list = new ArrayList<>();
         String ret="";//登录返回值随自己定义,
        //交给shiro进行认证
        Subject subject = SecurityUtils.getSubject();if(!subject.isAuthenticated()){
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            try {
                subject.login(token);
             // 剔除其他此账号在其它地方登录
                List<Session> loginedList = getLoginedSession(subject);
                for (Session session : loginedList) {
                    session.stop();
                } 
            } catch (UnknownAccountException ex1) {
                ex1.printStackTrace();
          ret = "账号错误";
} catch (IncorrectCredentialsException ex2) { ex2.printStackTrace();
          ret = "密码错误"; 
}catch (AuthenticationException ex3) { //ex3.printStackTrace();
          //ret = "该账号不存在";
ret = "账号或密码错误,请重新输入!"; list.add(ret); return list; } } return list; } //遍历同一个账户的session private List<Session> getLoginedSession(Subject currentUser) { Collection<Session> list = ((DefaultSessionManager) ((DefaultSecurityManager) SecurityUtils .getSecurityManager()).getSessionManager()).getSessionDAO() .getActiveSessions(); List<Session> loginedList = new ArrayList<Session>(); SysUser loginUser = (SysUser) currentUser.getPrincipal(); for (Session session : list) { Subject s = new Subject.Builder().session(session).buildSubject(); if (s.isAuthenticated()) { SysUser user = (SysUser) s.getPrincipal(); if (user.getId()==(loginUser.getId())) { if (!session.getId().equals(currentUser.getSession().getId())) { loginedList.add(session); } } } } return loginedList; } }

 6,jsp使用shiro标签,页面需要引入shiro标签库,

<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

//测试是否成功,name是后台查询出来存入shiro的user对象里的值,页面需要什么,后台就存什么。其他标签可自行百度
<shiro:user>
      <shiro:principal property="name"</shiro:principal>
</shiro:user>

列举如下几个页面常用标签:更多标签请百度。。。
<shiro:hasAnyRoles name="管理员,普通角色">
  123
</shiro:hasAnyRoles>//如果拥有管理员或者普通角色的其中一个,123就会显示。没有就不显示

<shiro:hasPermission name="1">//如果拥有权限1,456就会显示,没有就不显示
  456
</shiro:hasPermission>

<shiro:lacksPermission name="1">//除了有1权限的不会显示789,其他都能显示
  789
</shiro:lacksPermission>

controller注解式:
  @RequiresRoles("超级管理员")//拥有该角色可以访问

 


原文链接:https://www.cnblogs.com/ljmm/p/12582714.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:SpringBoot多环境分离resources和lib进行打包

下一篇:一次线上升级大规模报错后,我又重新学习了序列化!