`
san586
  • 浏览: 134786 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

Spring Security多登录口实现

阅读更多
ss3ex中配置的Spring Security一直是单登陆口,现改成多登录口,坚持少写代码的原则,但是不管怎么样,必须要解决以下几个问题:
1、用户未登录:访问权限页面,访问非权限页面
2、用户登录:访问权限页面(权限不够)
3、密码错误返回页面
4、注销页面
一个个问题来解决,第一个问题,用户未登录时访问访问非权限页面,直接就过了。麻烦的就是访问有权限的页面,因为Spring Security会使用AuthenticationEntryPoint在未登录用户访问被保护资源时自动跳转到登录页面,所以我们这里需要的就是扩展AuthenticaitonEntryPoint。
修改spring_security.xml文件:
<http auto-config="true" access-denied-page="/common/403.htm"
		entry-point-ref="loginPageEntryPoint">
		<intercept-url pattern="/login.**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
		<intercept-url pattern="/loginfont.**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
	……
<beans:bean id="loginPageEntryPoint" class="com.security.resource.LoginPageEntryPoint">
		<beans:property name="loginPageStrategy" ref="urlMappingLoginPageStrategy" />
	</beans:bean>
	<beans:bean id="urlMappingLoginPageStrategy"
		class="com.security.resource.UrlMappingLoginPageStrategy" />

LoginPageEntryPoint.java文件:
package com.security.resource;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.AuthenticationException;
import org.springframework.security.ui.AuthenticationEntryPoint;
import org.springframework.util.Assert;


public class LoginPageEntryPoint implements AuthenticationEntryPoint,
    InitializingBean {
    private LoginPageStrategy loginPageStrategy;

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(loginPageStrategy,
            "loginPageStrategy must be specified");
    }

    public void commence(ServletRequest request, ServletResponse response,
        AuthenticationException authException)
        throws IOException, ServletException {
        loginPageStrategy.process((HttpServletRequest) request,
            (HttpServletResponse) response);
    }

    public void setLoginPageStrategy(LoginPageStrategy loginPageStrategy) {
        this.loginPageStrategy = loginPageStrategy;
    }
}
LoginPageStrategy.java 接口文件:
package com.security.resource;

import java.io.IOException;

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


public interface LoginPageStrategy {
    void process(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException;
}
UrlMappingLoginPageStrategy.java文件:
package com.security.resource;

import java.io.IOException;

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


public class UrlMappingLoginPageStrategy implements LoginPageStrategy {
    public void process(HttpServletRequest request,
        HttpServletResponse response) throws IOException, ServletException {
        String targetUrl = null;
        String uri = request.getRequestURI();

        if (uri.indexOf("system") != -1) {
            targetUrl = "/login.jsp";
        } else {
            targetUrl = "/loginfont.jsp";
        }

        targetUrl = request.getContextPath() + targetUrl;
        response.sendRedirect(targetUrl);
    }
}
备注:别忘了在login.jsp同目录下复制一个jsp文件,取名叫loginfont.jsp。这2个文件代表着2个不同的登录口,表单提交的地址都是action="${base}/j_spring_security_check"。另外,因为多了一个登陆页面,他的权限也要放开,见上面修改的spring_security.xml文件。

第二个问题的解决方案有2个,分别是扩展AuthenticationProcessFilter,拦截403错误,还是根据url来判断跳转到不同的页面,这个方案我写了个类,开始抱着一定要实现的目的,由于逻辑上很多地方分散了,不好全部集中处理,后来觉得很麻烦,于是就放弃了。第二个方案相对来说,简单些,就是在用户登录时,往session中写进一个状态,如果不用session就用ThreadLocal,然后修改access-denied-page="/common/403.htm" 把这个页面改成一个action或者jsp的地址,在其中提取session中的值进行判断,跳转到不同的无权限错误页面。用户登录时写session有2个方案,一是,直接在ss3ex 中我配置的密码过滤器中操作(这个比较简单)。还有一个就是lingo介绍的自定义过滤器,他实现的步骤是:
添加spring_security.xml 文件
<!-- 自定义过滤器,刚开始由于没有配置authenticationFailureUrl属性,导致用户密码错误出错后,跳转页面不正常-->
	<beans:bean id="loginFilter" class="com.security.resource.LoginFilter">
<!-- 放置在AUTHENTICATION_PROCESSING_FILTER的前面-->
		<custom-filter before="AUTHENTICATION_PROCESSING_FILTER" />
<!-- 认证-->
		<beans:property name="authenticationManager" ref="authenticationManager" />
<!-- 认证错误页面-->
		<beans:property name="authenticationFailureUrl" value="/login.jsp?error=1" />  
<!-- 认证成功页面,必须的-->
		<beans:property name="defaultTargetUrl" value="/demo/success.shtml" />
	</beans:bean>
LoginFilter.java 文件:
package com.security.resource;

import javax.servlet.http.HttpServletRequest;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;

import com.utils.FakeSession;

public class LoginFilter extends AuthenticationProcessingFilter {

	public Authentication attemptAuthentication(HttpServletRequest request)
			throws AuthenticationException {
		Authentication authentication = super.attemptAuthentication(request);
		//状态, admin表示后台,font表示前台
		 String status = null;
	        String uri = request.getRequestURI();
	        if (uri.indexOf("system") != -1) {
	        	status = "admin";
	        } else {
	        	status = "font";
	        }
	        FakeSession.messageSegment.set(status);
		return authentication;
	}
}
FakeSession类(仿session)见我博客的另一篇文章。


第三个问题的解决方案,思路已经在第二个问题中解决了
<!-- 认证错误页面-->
		<beans:property name="authenticationFailureUrl" value="/login.jsp?error=1" />  

不过这里要修改下login.jsp,按照第二个问题的思路,写个判断的条件,根据ThreadLocal中status的状态跳转到不同的页面。

第四个问题的解决方案,注销页面,<logout logout-success-url="/login.jsp" invalidate-session="true" /> 也是修改这个页面,已经在第三个问题中解决了。

末:感谢狂人和lingo,提供的security的帮助,感谢小鸟提供的ThreadLocal。

老是有人问,再说详细点,补充如下(源代码在ss3ex中):
spring security2的流程
Spring Security会使用AuthenticationEntryPoint在未登录用户访问被保护资源时自动跳转到登录页面,自定义过滤器扩展AuthenticationProcessingFilter过滤器实现登录后,跳转页面前的后续操作,比如可以实现在跳转页面前往session中写入些内容。
Spring Security2多登录口实现
1、前后台登录页面;扩展AuthenticationEntryPoint过滤器
2、前后台认证成功页面;自定义过滤器扩展AuthenticationProcessingFilter过滤器
3、前后台认证失败页面;自定义过滤器扩展AuthenticationProcessingFilter过滤器
4、前后台无权限页面; access-denied-page
5、前后台注销返回页面。配置<logout logout-success-url="/login.jsp" invalidate-session="true" />标签
按照以上思路,可以实现无数个登录口。
分享到:
评论
2 楼 talangniao 2010-02-09  
String uri = request.getRequestURI(); 
获取到的都是/j_spring_security_check
这个能进行判断?返回哪个页面?
1 楼 talangniao 2010-02-09  
注销怎么返回不同的窗口?
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    spring-security2.zip

    4. **授权**:Spring Security通过`@PreAuthorize`和`@PostAuthorize`注解实现方法级别的权限控制。此外,可以使用访问决策管理器(Access Decision Manager)和访问决策投票器(Access Decision Voter)来定制授权...

    wicket-spring-security-example:Wicket SpringSecurity 示例

    Wicket SpringSecurity 示例 ###如何开始 mvn 全新安装 mvn 码头:运行 在浏览器中打开 ###做什么的 证明 Wicket 可以与 Spring Security 一起使用。 ### 演示 使用硬编码登录密码进行身份验证、角色授权、URL ...

    基于Spring Boot+Spring Security+JWT+Vue前后端分离的旺旺小小酥  ( 一口一口又香.zip

    这是一个关于构建基于Spring Boot、Spring Security、JSON Web Token (JWT) 和Vue.js的前后端分离项目的教程或示例代码。项目名为"旺旺小小酥",可能是为了形象地表示其小巧且美味,就像零食"旺旺小小酥"一样。下面...

    Springboot整合CXF发布Web service和客户端调用(用户和密码验证)

    3. 配置Spring Security以实现认证。 4. 使用CXF生成客户端代码。 5. 在客户端应用中创建代理对象并调用服务。 通过这种方式,你可以构建安全、可靠的Web服务,并在Spring Boot环境中轻松地进行客户端调用。

    JAVA网上拍卖系统的设计与实现(源代码+论文).zip

    《JAVA网上拍卖系统的设计与实现》是一份涵盖了Java编程、软件工程、电子商务等多个领域的综合性项目。这个系统的主要目标是提供一个安全、可靠的网上拍卖平台,让用户可以方便地进行在线竞拍活动。以下将从系统设计...

    wicket-kurs:使用 Spring 进行 Wicket 课程的基本起点

    4. **安全性配置**: 配置 Spring Security 或其他 Spring 相关的安全组件,实现登录、权限控制等功能。 5. **数据访问**: 利用 Spring JDBC 或 ORM 框架(如 Hibernate),实现数据持久化操作。 **最佳实践** 1. **...

    毕设项目:基于springboot+pi4j实现的智能家居系统.zip

    1. **用户认证与授权**:利用Spring Security进行用户身份验证和权限管理。 2. **API设计**:定义RESTful API,使得移动设备或网页可以发送控制指令。 3. **设备管理**:管理家庭中的智能设备信息,包括设备注册、...

    基于ssm框架的拍卖系统.zip

    安全方面,利用Spring Security或Apache Shiro进行权限控制,防止未授权访问。 总的来说,"基于SSM框架的拍卖系统"项目涵盖了Java Web开发的多个重要环节,包括后端架构设计、数据库设计、前端交互以及安全策略,...

    【Java毕业设计】Java基于SSM拍卖社交网站设计毕业源码案例设计.zip

    使用Spring Security可以实现安全的身份验证和授权,确保用户数据的安全。 6. **社交功能**:拍卖网站通常包含社交元素,如好友系统、评论、收藏、分享等。这些功能需要数据库表设计和相应的业务逻辑来支持。 7. *...

    基于SpringBoot + Vue的仓库管理系统的设计与实现

    Spring Security或JWT(JSON Web Tokens)可用来处理用户认证和授权,确保系统安全性。数据库方面,通常会选用MySQL或者PostgreSQL存储商品信息、库存状态以及操作日志等数据,同时,可能还会运用Redis来缓存部分...

    Java基于SSM拍卖社交网站设计源码案例设计.zip

    - 安全性:使用Spring Security进行权限控制和防止XSS、CSRF等攻击。 - 日志系统:如Log4j,记录系统运行日志,便于调试和监控。 通过分析这个压缩包中的"code-337",我们可以深入研究上述技术在实际项目中的应用...

    java+vue医院管理系统(源码)

    同时,Spring Security则为系统提供了安全防护,确保数据的安全性。 Vue.js作为前端框架,以其轻量级、高性能和组件化的特性,极大地提高了开发效率。Vue.js的响应式数据绑定和虚拟DOM技术,使得用户界面的更新更为...

    检票口

    此外,还可以使用Spring Security等库进行权限控制,防止非法访问。 7. **日志记录**:利用Log4j或SLF4J等日志框架记录操作日志,便于系统维护和问题排查。 8. **单元测试与集成测试**:使用JUnit和Mockito等工具...

Global site tag (gtag.js) - Google Analytics