耀眼的橘子的gravatar头像
耀眼的橘子 2017-04-18 14:20:45
apache shiro安全框架 登录,记住我,前后台分离

最近做的项目,由于客户需求,登录的用户信息必须经过身份验证,自己研究了一下,写个博客与大家分享一下我的心得。本次项目用到了shiro的登录,记住我,前后台分离功能。这里只做了登录认证,没有权限管理。

项目构建:

在pom.xml文件:

                  <dependency>
			<groupId>org.apache.shiro</groupId>
			<artifactId>shiro-spring</artifactId>
                       <version>1.2.3 </version>
		</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-cas</artifactId>
                          <version>1.2.3 </version>
		</dependency>

 在 web.xml文件里:

        <context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml,classpath:shiro/spring-context-shiro.xml</param-value>
	</context-param>



    <filter>
		<filter-name>shiroFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy
		</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>shiroFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

shrio配置文件  spring-context-shiro:

<?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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context-4.0.xsd"
    default-lazy-init="true">

    <description>Shiro Configuration</description>
	 <!--多个realm 的集中管理  -->
    <bean id="defineModularRealmAuthenticator" class="包路径.DefautModularRealm"> 
        <property name="definedRealms">    
            <map>    
                <entry key="systemAuthorizingRealm" value-ref="systemAuthorizingRealm" />    
                <entry key="userAuthorizingRealm" value-ref="userAuthorizingRealm" />    
            </map>   
        </property>  
        <!-- <property name="authenticationStrategy">    
            <bean class="org.apache.shiro.authc.pam.FirstSuccessfulStrategy" />    
        </property> --> 
    </bean>   
	
    <!-- Shiro权限过滤过滤器定义 -->
    <bean name="shiroFilterChainDefinitions" class="java.lang.String">
        <constructor-arg>
            <value>
                /userMember/login = authc
                /logout = logout
                /apply/** = user
                /alter/** = user 
            </value>
        </constructor-arg>
    </bean>

    <!-- 安全认证过滤器 -->
    <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
        <property name="securityManager" ref="securityManager" />
        <property name="loginUrl" value="/userMember/login" />
        <property name="successUrl" value="/home/forward" />
        <property name="filters">
            <map>
                <entry key="cas" value-ref="casFilter" />
                <entry key="authc" value-ref="formAuthenticationFilter" />
                <entry key="logout" value-ref="logoutFilter" />
            </map>
        </property>
        
        <property name="filterChainDefinitions">
            <ref bean="shiroFilterChainDefinitions" />
        </property>
    </bean>
	
	<bean id="logoutFilter" class="org.apache.shiro.web.filter.authc.LogoutFilter">
     <property name="redirectUrl" value="/home/forward" />
	</bean>
	
    <bean id="casFilter" class="org.apache.shiro.cas.CasFilter">
        <!--配置验证错误时的失败页面 /main 为系统登录页面 -->
        <property name="failureUrl" value="/message.jsp" />
    </bean>
    <!-- 基于Form表单的身份验证过滤器 -->
    <bean id="formAuthenticationFilter"
        class="包路径.FormAuthenticationFilter">
        <property name="usernameParam" value="name" />
        <property name="passwordParam" value="password" />
        <property name="logintypeParam" value="logintype" />
        <property name="loginUrl" value="/login.jsp" /> 
        <property name="rememberMeParam" value="rememberMe"/> 
    </bean>
    

    <!-- 定义Shiro安全管理配置 -->
    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="authenticator" ref="defineModularRealmAuthenticator" /> 
         <!-- 这里主要是设置自定义的单Realm应用,若有多个Realm,可使用'realms'属性代替 -->
     		<!-- <property name="realm" ref="loginRealm"/> -->
        <property name="realms"  >
            <list>
               <bean id="systemAuthorizingRealm"
                class="包路径.SystemAuthorizingRealm" /> 
               <bean id="userAuthorizingRealm"
        		class="包路径.UserAuthorizingRealm" /> 
            </list>
        </property>
        
        <!-- <property name="sessionManager" ref="sessionManager" /> -->
        <property name="cacheManager" ref="memoryConstrainedCacheManager" />
        <property name="rememberMeManager" ref="rememberMeManager"/>  
    </bean>
	
    <bean id="systemAuthorizingRealm"
        class="包路径.SystemAuthorizingRealm">
    </bean>
    
    <bean id="userAuthorizingRealm"
        class="包路径.UserAuthorizingRealm">
    </bean>
    
    <!-- 定义授权缓存管理器 -->
    <bean id="shiroCacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="cacheManager" />
    </bean>
    <bean id="memoryConstrainedCacheManager" class="org.apache.shiro.cache.MemoryConstrainedCacheManager" />

    <!-- 自定义会话管理配置 -->
	<!-- 指定本系统SESSIONID, 默认为: JSESSIONID 问题: 与SERVLET容器名冲突, 如JETTY, TOMCAT 等默认JSESSIONID, 
        当跳出SHIRO SERVLET时如ERROR-PAGE容器会为JSESSIONID重新分配值导致登录会话丢失! -->
    <bean id="sessionManager"
        class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
        <property name="sessionDAO" ref="sessionDAO" />
        <!-- 会话超时时间,单位:毫秒 -->
        <property name="globalSessionTimeout" value="${session.sessionTimeout}" />
        <!-- 定时清理失效会话, 清理用户直接关闭浏览器造成的孤立会话 -->
        <property name="sessionValidationInterval" value="${session.sessionTimeoutClean}" />
        <!-- <property name="sessionValidationSchedulerEnabled" value="false"/> -->
        <property name="sessionValidationSchedulerEnabled" value="true" />
        <property name="sessionIdCookie" ref="sessionIdCookie" />
        <property name="sessionIdCookieEnabled" value="true" />
    </bean>
	
	    <!-- 会话Cookie模板 -->  
    <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
        <constructor-arg name="name" value="applyid" />
        <property name="httpOnly" value="true"/>  
        <property name="maxAge" value="-1"/>  
    </bean>  
    
    <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">  
        <constructor-arg value="rememberMe"/>  
        <property name="httpOnly" value="true"/>  
        <property name="maxAge" value="604800"/><!-- 7天 -->  
    </bean> 
      
    <!-- rememberMe管理器 -->  
	<bean id="rememberMeManager"   
	class="org.apache.shiro.web.mgt.CookieRememberMeManager">  
	    <property name="cipherKey" 
	    value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"/>  
	     <property name="cookie" ref="rememberMeCookie"/>  
	</bean> 

    <bean id="sessionDAO" 
        class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
        <!-- <property name="activeSessionsCacheName" value="shiro-activeSessionCache"/> -->
        <property name="cacheManager" ref="shiroCacheManager" />
    </bean>

    <!-- 保证实现了Shiro内部lifecycle函数的bean执行 -->
    <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

</beans>

在这里有一个 logintype,这个变量是我,是我自定义的,本身的shrio是没有,是做前后台登录的标志位。

 

FormAuthenticationFilter 类:

package 包路径;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FormAuthenticationFilter extends org.apache.shiro.web.filter.authc.FormAuthenticationFilter {
	/**
	 * logger日志
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 序列化id
	 */
	private static final long serialVersionUID = -2271706136984114038L;
	/**
	 * 登录类型
	 */
	public static final String DEFAULT_LOGINTYPE_PARAM = "logintype";

	private String logintypeParam = DEFAULT_LOGINTYPE_PARAM;
	
	

	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		String logintype = getLogintype(request);
		logger.debug("createToken username:{},password:{},loginType:{"+logintype+"} ...",username,password);
		if (password==null){
			password = "";
		}
		String host = getRemoteAddr((HttpServletRequest)request);
        boolean rememberMe = isRememberMe(request);
        return new UsernamePasswordToken(username, password.toCharArray(), rememberMe, host, logintype);
	}
	
	public void setLogintypeParam(String logintypeParam) {
        this.logintypeParam = logintypeParam;
    }
	
	public String getLogintypeParam() {
		return logintypeParam;
	}
	
	protected String getLogintype(ServletRequest request) {
		return WebUtils.getCleanParam(request, getLogintypeParam());
	}
	/**
	 * 获得用户远程地址
	 */
	public static String getRemoteAddr(HttpServletRequest request){
		String remoteAddr = request.getHeader("X-Real-IP");
        if (StringUtils.isNotBlank(remoteAddr)) {
        	remoteAddr = request.getHeader("X-Forwarded-For");
        }else if (StringUtils.isNotBlank(remoteAddr)) {
        	remoteAddr = request.getHeader("Proxy-Client-IP");
        }else if (StringUtils.isNotBlank(remoteAddr)) {
        	remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        }
        return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
	}
}

UsernamePasswordToken 类:

package 包路径;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UsernamePasswordToken extends org.apache.shiro.authc.UsernamePasswordToken {
	/**
	 * logger日志
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 序列化id
	 */
	private static final long serialVersionUID = -2271706136984114038L;
	/**
	 * 登录类型
	 */
	private String logintype ;
	
	
	public String getLogintype() {
		return logintype;
	}

	public void setLogintype(String logintype) {
		this.logintype = logintype;
	}
	
	public UsernamePasswordToken (String username, char[] password,
			boolean rememberMe, String host, String logintype) {
		super(username, password, rememberMe, host);
        this.logintype = logintype;
	}

}

DefautModularRealm 类,多个realm集中管理:

package 包路径;

import java.util.Collection;
import java.util.Map;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.util.CollectionUtils;

import 系统文件路径.SysConstant;

public class DefautModularRealm extends org.apache.shiro.authc.pam.ModularRealmAuthenticator{
	
	private Map<String, Object> definedRealms;  

    /** 
     * 多个realm实现 
     */  
    @Override  
    protected AuthenticationInfo doMultiRealmAuthentication(Collection<Realm> realms, AuthenticationToken token) {  
        return super.doMultiRealmAuthentication(realms, token);  
    }  
    
    /** 
     * 调用单个realm执行操作 
     */  
    @Override  
    protected AuthenticationInfo doSingleRealmAuthentication(Realm realm,AuthenticationToken token) {  
        // 如果该realms不支持(不能验证)当前token  
        if (!realm.supports(token)) {  
            throw new ShiroException("token错误!");  
        }  
        AuthenticationInfo info = null;  
        try {  
            info = realm.getAuthenticationInfo(token);  
            if (info == null) {  
                throw new ShiroException("token不存在!");  
            }  
        } catch (Exception e) {  
            throw new ShiroException("用户名或者密码错误!");  
        }  
        return info;  
    } 


    /** 
     * 判断登录类型执行操作 
     */  
    @Override  
    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)throws AuthenticationException {  
        this.assertRealmsConfigured();  
        Realm realm = null;  
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;  
       //判断是否是后台用户
        if (token.getLogintype().equals(SysConstant.FRONT_LOGIN)) {  
            realm = (Realm) this.definedRealms.get("systemAuthorizingRealm");  
        }  
        else if (token.getLogintype().equals(SysConstant.ADMIN_LOGIN)){
            realm = (Realm) this.definedRealms.get("userAuthorizingRealm");  
        }

        return this.doSingleRealmAuthentication(realm, authenticationToken);  
    }  

    /** 
     * 判断realm是否为空 
     */  
    @Override  
    protected void assertRealmsConfigured() throws IllegalStateException {  
        this.definedRealms = this.getDefinedRealms();  
        if (CollectionUtils.isEmpty(this.definedRealms)) {  
            throw new ShiroException("值传递错误!");  
        }  
    }  

    public Map<String, Object> getDefinedRealms() {  
        return this.definedRealms;  
    }  

    public void setDefinedRealms(Map<String, Object> definedRealms) {  
        this.definedRealms = definedRealms;  
    }

}

SystemAuthorizingRealm  后台认证realm

package 包路径;

import javax.annotation.PostConstruct;
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.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import 系统文件路径.ENUM_SYSTEM;
import 系统文件路径.重写后台用户实体类.Principal;
import 系统文件路径.后台用户实体类.UserMemberDO;
import 系统文件路径.后台用户服务.UserMemberService;

@Service
public class SystemAuthorizingRealm extends AuthorizingRealm {
	/**
	 * logger日志
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 序列化id
	 */
	private static final long serialVersionUID = -2271706136984114038L;
	/**
	 * userMemberServicef服务
	 */
	@Resource
	private UserMemberService userMemberService;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermission("sys:manager");
		info.addStringPermission("user");
		System.out.println("开始授权");
		return info;
	}

	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
		UserMemberDO user = userMemberService.getByName(token.getUsername());
		if (user == null ) {
			throw new UnknownAccountException("用户名不存在");
		} else if (ENUM_SYSTEM.ACCOUNT_VERIFICATION_NO.getKey().equals(user.getStatus())) {
			throw new DisabledAccountException("账户未审核通过!");
		}
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(new Principal(user), user.getPassword(), null,
				getName());
		return authenticationInfo;
	}

	/**
	 * 设定密码校验的MD5算法与迭代次数
	 */
	@PostConstruct
	public void initCredentialsMatcher() {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");
		setCredentialsMatcher(matcher);
	}

	@Override
	protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	protected void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthorizationInfo();
		clearAllCachedAuthenticationInfo();
	}

	
}

UserAuthorizingRealm 前台用户认证realm

package 包路径.shiro;

import javax.annotation.PostConstruct;
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.DisabledAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import 系统路径.ENUM_SYSTEM;
import 系统路径.重写前台用户实体类.user.Principal;
import 系统路径.前台用户实体类.user.UserDO;
import 系统路径.前台用户服务.user.UserService;

@Service
public class UserAuthorizingRealm extends AuthorizingRealm {
	/**
	 * logger日志
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 序列化id
	 */
	private static final long serialVersionUID = -2271706136984114038L;
	/**
	 * userMemberServicef服务
	 */
	@Resource
	private UserService userService;

	/**
	 * 授权
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermission("sys:manager");
		info.addStringPermission("user");
		System.out.println("开始授权");
		return info;
	}

	/**
	 * 认证
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
			throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
		System.out.println(token.getUsername());
		UserDO user = userService.getByName(token.getUsername());
		if (user == null ) {
			throw new UnknownAccountException("用户名不存在");
		} 
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(new Principal(user), user.getPassword(), null,
				getName());
		return authenticationInfo;
	}

	/**
	 * 设定密码校验的MD5算法与迭代次数
	 */
	@PostConstruct
	public void initCredentialsMatcher() {
		HashedCredentialsMatcher matcher = new HashedCredentialsMatcher("MD5");
		setCredentialsMatcher(matcher);
	}

	@Override
	protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}

	@Override
	protected void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}

	@Override
	protected void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}

	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}

	public void clearAllCache() {
		clearAllCachedAuthorizationInfo();
		clearAllCachedAuthenticationInfo();
	}

	
}

在这里有一个这样的一个类Principal这个类的作用主要是在用户登录的时候shiro保存登录信息,包括id ,姓名,密码,状态。等等。可以自定义。在JSP标签里的输出对象,在下面有讲。

前台登录controller:

package 系统路径.controller.usermember;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;

import 系统路径.前台用户实体类.Principal;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

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


@Controller
@RequestMapping("userMember")
public class UserMemberController extends BaseController<UserMemberDO> {
	/**
	 * logger日志
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	/**
	 * 序列化id
	 */
	private static final long serialVersionUID = -2271706136984114038L;

	/**
	 * 登录
	 * @param request 请求
	 * @param response 响应
	 * @param member 前台用户对象
	 * @param model 模板
	 * @return String 页面
	 */
	@RequestMapping(value = "/login")
	public String login(HttpServletRequest request, HttpServletResponse response,
			@ModelAttribute("member") UserMemberDO member, ModelMap model) {
		logger.info("login...");
		
		Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        // 如果已经登录,则跳转到管理首页
        if (principal != null) {
            return "redirect:/home/forward"; // 首页
        }
		
		String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
		String errorMsg = null;
		if (UnknownAccountException.class.getName().equals(exceptionClassName)) {
			logger.info("该用户名不存在");
			errorMsg = "该用户名不存在";
		} else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) {
			logger.info("密码错误");
			errorMsg = "密码错误";
		} else if (DisabledAccountException.class.getName().equals(exceptionClassName)) {
			logger.info("该账号审核未通过");
			errorMsg = "该账号审核未通过";
		} else if (exceptionClassName != null) {
			logger.info("登录错误" + exceptionClassName);
			errorMsg = "登录错误";
		}
		model.addAttribute("errorMsg", errorMsg);
		return PAGE_LOGIN;
	}

}

这里我只写出前台登录的controller,后台的登录controller一样就不贴出了。

在JSP页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ include file="/view/common/include.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录</title>

<script type="text/javascript" src="${ctxStatic }/js/login/login.js"></script>
<script>

</script>
</head>
<body>

	<div class="container-login" id="div1">
		<img src="${ctxStatic }/img/bj.png" />
	</div>

	<div class="container-login" id="div1">
			<img src="${ctxStatic }/img/bj.png" />
		</div>
        <div class="content-all-login">
			
			<div class="content-login">
			<form action="${ctx}/userMember/login" method="post" id="loginform" >
				<div class="content-title">
			       <h3>登录</h3>
		        </div>
		        <div class="form-group">
	                <input type="text" id="name" name="name" class="form-control text1" value="tom123" placeholder="输入用户名"/>
	            </div>
				<div class="form-group">
	                  <input type="password" id="password" name="password" value="000000"class="form-control text2" placeholder="密码"/>
	                  <input type="text" id="logintype" name="logintype" value="0" style="display:none"/>
	            </div>
	             <div class="wrong"><label id="errorMsg">${errorMsg}</label></div>
			<div class="row row-mian">
			<div class="col-sm-6" style="padding-left: 0px;text-align: left;">
		<input type="checkbox" value="true" id="rememberMe" name="rememberMe"/>
						<span class="login-seven">七天免登陆<span>
					</div>
			<div class="col-sm-6" style="padding-right: 0px;text-align: right;">
			<a href="" class="forgetPassword">忘记密码</a>
					</div>
					<div>
			<button type="submit"class="btn btn-primary" style="margin-top: 25px;width: 232px;background: #0094fd;height: 40px;">登录</button>
					</div>
				</div>
			  </form>
			</div>
    </div> 
    
</body>
</html>

登录成功以后,如何显示的登录者的用户名。在这里shrio有自己的页面标签:

首先导入 标签:

<%@taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> 
<shiro:guest>  
		<a href=""">登录</a>|
		<a href="" class="registered">注册</a>
</shiro:guest>
<shiro:user>  
	<a class="login">你好:[<shiro:principal property="name"/>]</a> 
		<span id="center-info">
			<ul>
		            <li class="dropdown" id="accountmenu" style="margin-right: 0px;">
				<a class="center-in" style="width: 130px;display: inline-block;font-weight: 400;">
					个人中心<b class="caret"></b></a>
				 <ul class="dropdown-menu" style="display: none;" id="center">
		            <li><a href="${ctx}/userMember/center" style="font-weight: 400;">基本信息</a></li>
		            <li><a href="${ctx}/userMember/history" style="font-weight: 400;">历史申请记录</a></li>
	                   </ul>
			</li>
		</ul>
		</span>
		<a href="${ctx }/alter/message" class="login">消息</a>
		 <a href="${ctx }/logout" class="login">退出</a>
</shiro:user>

这里详细的就不贴出了,也就不详细说明了。只是告诉大家,有这样一个途径,就不用费尽心思的还要把信息封装到session 里面了。一开始,我不知道有这样的途径,所以,把信息封装到了session里面了,这真的是多此一举。


打赏

已有1人打赏

hackxhao的gravatar头像
最近浏览
penghongyou  LV2 2021年8月28日
Misshuang  LV13 2021年5月24日
jljkhyc  LV1 2020年7月31日
35454dfd  LV1 2020年7月15日
未来的光明  LV6 2020年7月14日
cwx1234  LV11 2020年7月13日
妈妈妈妈妈妈  LV8 2020年5月10日
zhouzh  LV9 2020年4月21日
sunchao  LV6 2020年3月31日
shmilqdd 2020年3月6日
暂无贡献等级
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友