shiro管理多登录入口配置,手机端登录与网页端登录

shiro管理多登录入口配置,手机端登录与网页端登录

1、2个Realm:分别为手机端、网页端的

/**
 * 自定义MobileRealm .
 */
public class MobileRealm extends AuthorizingRealm {
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {	
		return null;
	}
	@Override
	// 验证的核心方法
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String userCode = (String) token.getPrincipal();
		UsernamePasswordToken usernamePassword = (UsernamePasswordToken) token;
		char[] passWord = usernamePassword.getPassword();
		if (StringUtil.isEmpty(userCode)) {
			throw new UserNameNullException();// 账号为空
		}
		if (StringUtil.isEmpty(passWord)) {
			throw new PassWordNullException();// 密码为空
		}
		// 根据登录名查询操作员
		Admin operator = null;
		try {
			operator = adminService.getAdminUserByUserCode(userCode);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (operator == null) {
			throw new UnknownAccountException();// 没找到帐号
		}

		if (!Constants.UserLockStatus.UNLOCK.equals(operator.getLock_status())) {
			throw new LockedAccountException(); // 账号锁定或者不是生效状态
		}
		if (!Constants.UserStatus.OPEN.equals(operator.getUser_status())) {
			throw new LockedAccountException(); // 账号锁定或者不是生效状态
		}
		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(operator.getUser_name(), // 登录名
				operator.getUser_pswd(), // 密码
				getName() // realm name
		);
		return authenticationInfo;
	}
	@Override
	public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
		super.clearCachedAuthorizationInfo(principals);
	}
	@Override
	public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
		super.clearCachedAuthenticationInfo(principals);
	}
	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}
	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}
	public void clearAllCachedAuthenticationInfo() {
		getAuthenticationCache().clear();
	}
	public void clearAllCache() {
		clearAllCachedAuthenticationInfo();
		clearAllCachedAuthorizationInfo();
	}
}
/**
 * 自定义realm .
 *
 */
public class WebRealm extends AuthorizingRealm {

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		return null;
	}
	@Override
	// 验证的核心方法
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String userCode = (String) token.getPrincipal();
		UsernamePasswordToken usernamePassword = (UsernamePasswordToken) token;
		char[] passWord = usernamePassword.getPassword();
		if (StringUtil.isEmpty(userCode)) {
			throw new UserNameNullException();// 账号为空
		}
		if (StringUtil.isEmpty(passWord)) {
			throw new PassWordNullException();// 密码为空
		}
		// 根据登录名查询操作员
		Admin operator = null;
		try {
			operator = adminService.getAdminUserByUserCode(userCode);
		} catch (Exception e) {
			e.printStackTrace();
		}

		if (operator == null) {
			throw new UnknownAccountException();// 没找到帐号
		}

		if (!Constants.UserLockStatus.UNLOCK.equals(operator.getLock_status())) {
			throw new LockedAccountException(); // 账号锁定或者不是生效状态
		}
		if (!Constants.UserStatus.OPEN.equals(operator.getUser_status())) {
			throw new LockedAccountException(); // 账号锁定或者不是生效状态
		}
		// 交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配
		SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(operator.getUser_name(), // 登录名
				operator.getUser_pswd(), // 密码
				getName() // realm name
		);

		return authenticationInfo;

	}

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

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

	@Override
	public void clearCache(PrincipalCollection principals) {
		super.clearCache(principals);
	}
	public void clearAllCachedAuthorizationInfo() {
		getAuthorizationCache().clear();
	}

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

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

2、2个自定义form表单认证过滤器:分别为手机端、网页端的

/**
 * 自定义webform表单认证过滤器<br/>
 */
public class WebFormAuthenticationFilter extends FormAuthenticationFilter {
	public static final String LOGIN_TYPE = LoginType.WEB.toString();
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession();
		//将版本号保存到session中
		if (session.getAttribute(Constants.SESSION_VERSION) == null) {
			session.setAttribute(Constants.SESSION_VERSION,Constants.SESSION_VERSION_NO);
		}
		if (request.getAttribute(getFailureKeyAttribute()) != null) {
			return true;
		}
		return super.onAccessDenied(request, response, mappedValue);
	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		WebUtils.getAndClearSavedRequest(request);
		WebUtils.redirectToSavedRequest(request, response, "/index");// 页面跳转到首页
		return false;
	}

	@Override
	protected UserPasswordToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		return new UserPasswordToken(username, password.toCharArray(),LOGIN_TYPE);
	}
}
/**
 * 自定义mobileform表单认证过滤器<br/>
 */
public class MobileFormAuthenticationFilter extends FormAuthenticationFilter {

	public static final String LOGIN_TYPE = LoginType.MOBILE.toString();
	
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response, Object mappedValue)
			throws Exception {
		Subject subject = SecurityUtils.getSubject();
		Session session = subject.getSession();
		//将版本号保存到session中
		if (session.getAttribute(Constants.SESSION_VERSION) == null) {
			session.setAttribute(Constants.SESSION_VERSION,Constants.SESSION_VERSION_NO);
		}
		if (request.getAttribute(getFailureKeyAttribute()) != null) {
			return true;
		}
		return super.onAccessDenied(request, response, mappedValue);
	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		WebUtils.getAndClearSavedRequest(request);
		WebUtils.redirectToSavedRequest(request, response, "/mobile/index");// 页面跳转到首页
		return false;
	}
	@Override
	protected UserPasswordToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		String password = getPassword(request);
		return new UserPasswordToken(username, password.toCharArray(),LOGIN_TYPE);
	}
}

3、登录方式区分
(1)登录类型定义

public enum LoginType {
	WEB("Web"),  MOBILE("Mobile");
    private String type;
    private LoginType(String type) {
        this.type = type;
    }
    @Override
    public String toString() {
        return this.type.toString();
    }
}

(2)添加logintype

public class UserPasswordToken extends UsernamePasswordToken {
	 
	private static final long serialVersionUID = -1L;
	
	private String loginType;
 
	public UserPasswordToken(String username, char[] password,String loginType) {
		super(username, password);
		this.loginType = loginType;
	}
	
	public String getLoginType() {
		return loginType;
	}
 
	public void setLoginType(String loginType) {
		this.loginType = loginType;
	}
}

(3)判断登录

/**
 *  自定义Authenticator
 * 注意,对应Realm的类名要分别包含字符串“Mobile”或“Web”,
 *不能一个类名同时包含两个字符串,否则无法选择Realm
 * @author yigai
 *
 */
public class ModelRealmAuthenticator extends ModularRealmAuthenticator{
		@Override
	    protected AuthenticationInfo doAuthenticate(AuthenticationToken authenticationToken)
	            throws AuthenticationException {
	        assertRealmsConfigured();
	       UserPasswordToken customizedToken = (UserPasswordToken) authenticationToken;
	        String loginType = customizedToken.getLoginType();
	        Collection<Realm> realms = getRealms();
	        Collection<Realm> loginRealms = new ArrayList<>();
	        for (Realm realm : realms) {
	            if (realm.getName().contains(loginType))
	                loginRealms.add(realm);
	        }
	        if (typeRealms.size() == 1)
	            return doSingleRealmAuthentication(loginRealms.iterator().next(), customizedToken);
	        else
	            return doMultiRealmAuthentication(loginRealms, customizedToken);
	    }
	}

4、xml配置

<!-- 自定义的web Realm实现 -->
	<bean id="webRealm" class="com.shiro.WebRealm">
		<property name="credentialsMatcher" ref="credentialsMatcher" />
		<property name="cachingEnabled" value="false" />
		<!--<property name="authorizationCachingEnabled" value="true"/> -->
		<!--<property name="authorizationCacheName" value="authorizationCache"/> -->
	</bean>
	<!-- 自定义的mobile Realm实现 -->
	<bean id="mobileRealm" class="com.shiro.MobileRealm">
		<property name="credentialsMatcher" ref="credentialsMatcher" />
		<property name="cachingEnabled" value="false" />
		<!--<property name="authorizationCachingEnabled" value="true"/> -->
		<!--<property name="authorizationCacheName" value="authorizationCache"/> -->
	</bean>

	<!-- 安全管理器 -->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="authenticator" ref="authenticator" />
		 <!-- 可以配置多个Realm,realms属性被赋值给ModelRealmAuthenticator的realms属性 -->
        <property name="realms">
            <list>
                <ref bean="webRealm" />
                <ref bean="mobileRealm"/>
            </list>
        </property>
	</bean>
	<!-- 配置使用自定义认证器,实现多Realm认证-->
    <bean id="authenticator" class="com.shiro.ModelRealmAuthenticator">
        <property name="authenticationStrategy">
            <bean class="org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy"></bean>
        </property>
    </bean>
	<!-- 基于Form表单的身份验证过滤器 -->
	<bean id="authcFilter"
		class="com.shiro.FormAuthenticationFilter">
		<!-- from表达提交参数的属性命名 -->
		<property name="usernameParam" value="userAccount" />
		<property name="passwordParam" value="password" />
		<!--<property name="rememberMeParam" value="rememberMe" /> -->
		<property name="loginUrl" value="/login" />
		<property name="failureKeyAttribute" value="shiroLoginFailure" />
	</bean>
	<bean id="mobileFilter"		class="com.shiro.MobileFormAuthenticationFilter">
		<!-- from表达提交参数的属性命名 -->
		<property name="usernameParam" value="userAccount" />
		<property name="passwordParam" value="password" />
		<!--<property name="rememberMeParam" value="rememberMe" /> -->
		<property name="loginUrl" value="/mobile/login" />
		<property name="failureKeyAttribute" value="shiroLoginFailure" />
	</bean>

	<!-- 验证码验证过滤器 -->
	<bean id="captchaValidateFilter"
		class="com.shiro.CaptchaValidateFilter">
		<property name="captchaEbabled" value="true" />
		<property name="captchaParam" value="captchaCode" />
		<property name="failureKeyAttribute" value="shiroLoginFailure" />
	</bean>
	<!-- Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 -->
	<!-- Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截,Shiro对基于Spring的Web应用提供了完美的支持 -->
	<bean id="shiroFilter"
		class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 登录controller的mapper地址 -->
		<property name="loginUrl" value="/login" />
		<!-- <property name="successUrl" value="/index"/>  -->
		<property name="filters">
			<util:map>
				<entry key="captchaValidate" value-ref="captchaValidateFilter" />
				<entry key="authc" value-ref="authcFilter" />
				<entry key="mobile" value-ref="mobileFilter" />
			</util:map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/js/**=anon
				/images/**=anon
				/login =captchaValidate,authc
				/mobile/login =captchaValidate,mobile
				/logout=authc
				/index=authc
				/mobile/index=mobile
				/** = authc
				/** = mobile
			</value>
		</property>

5、2个controller:
(1)WebController

@RequestMapping(value = "/", method = { RequestMethod.POST, RequestMethod.GET })
	public String index() {
		return "redirect:/login";
	}
	@RequestMapping(name = "首页", value = "/index", produces = "text/html;charset=UTF-8")
	public String index(Model model) {
		return "adminUser/index";
	}

	/**
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value =  "/login")
	public String login(HttpServletRequest request, Model model) {

		logger.info("login start.");
		String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
		String error = null;
		...
		// 如果没有错误 并且 session中的AdminUser不为空
		if (StringUtils.isEmpty(error) && null != session.getAttribute(Constants.SESSION_KEY_ADMIN_USER)) {
			logger.info("login end.");
			return "redirect:/index";
		}
	
		logger.info("login end.");
		return "system/login";
	}

(2)MobileController

@RequestMapping(value = "/mobile", method = { RequestMethod.POST, RequestMethod.GET })
	public String index() {
		return "redirect:/mobile/login";
	}
	@RequestMapping(name = "首页", value = "/index", produces = "text/html;charset=UTF-8")
	public String index(Model model) {
		return "/mobile/index";
	}

	/**
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping(value =  "/mobile/login")
	public String login(HttpServletRequest request, Model model) {

		logger.info("login start.");
		String exceptionClassName = (String) request.getAttribute("shiroLoginFailure");
		String error = null;
		...
		// 如果没有错误 并且 session中的AdminUser不为空
		if (StringUtils.isEmpty(error) && null != session.getAttribute(Constants.SESSION_KEY_ADMIN_USER)) {
			logger.info("login end.");
			return "redirect:/mobile/index";
		}
	
		logger.info("login end.");
		return "mobile/login";
	}

到这就可以完成多登录入口配置,稍后上传详细文件资源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值