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" />标签
按照以上思路,可以实现无数个登录口。
分享到:
相关推荐
4. **授权**:Spring Security通过`@PreAuthorize`和`@PostAuthorize`注解实现方法级别的权限控制。此外,可以使用访问决策管理器(Access Decision Manager)和访问决策投票器(Access Decision Voter)来定制授权...
Wicket SpringSecurity 示例 ###如何开始 mvn 全新安装 mvn 码头:运行 在浏览器中打开 ###做什么的 证明 Wicket 可以与 Spring Security 一起使用。 ### 演示 使用硬编码登录密码进行身份验证、角色授权、URL ...
这是一个关于构建基于Spring Boot、Spring Security、JSON Web Token (JWT) 和Vue.js的前后端分离项目的教程或示例代码。项目名为"旺旺小小酥",可能是为了形象地表示其小巧且美味,就像零食"旺旺小小酥"一样。下面...
3. 配置Spring Security以实现认证。 4. 使用CXF生成客户端代码。 5. 在客户端应用中创建代理对象并调用服务。 通过这种方式,你可以构建安全、可靠的Web服务,并在Spring Boot环境中轻松地进行客户端调用。
《JAVA网上拍卖系统的设计与实现》是一份涵盖了Java编程、软件工程、电子商务等多个领域的综合性项目。这个系统的主要目标是提供一个安全、可靠的网上拍卖平台,让用户可以方便地进行在线竞拍活动。以下将从系统设计...
4. **安全性配置**: 配置 Spring Security 或其他 Spring 相关的安全组件,实现登录、权限控制等功能。 5. **数据访问**: 利用 Spring JDBC 或 ORM 框架(如 Hibernate),实现数据持久化操作。 **最佳实践** 1. **...
1. **用户认证与授权**:利用Spring Security进行用户身份验证和权限管理。 2. **API设计**:定义RESTful API,使得移动设备或网页可以发送控制指令。 3. **设备管理**:管理家庭中的智能设备信息,包括设备注册、...
安全方面,利用Spring Security或Apache Shiro进行权限控制,防止未授权访问。 总的来说,"基于SSM框架的拍卖系统"项目涵盖了Java Web开发的多个重要环节,包括后端架构设计、数据库设计、前端交互以及安全策略,...
使用Spring Security可以实现安全的身份验证和授权,确保用户数据的安全。 6. **社交功能**:拍卖网站通常包含社交元素,如好友系统、评论、收藏、分享等。这些功能需要数据库表设计和相应的业务逻辑来支持。 7. *...
Spring Security或JWT(JSON Web Tokens)可用来处理用户认证和授权,确保系统安全性。数据库方面,通常会选用MySQL或者PostgreSQL存储商品信息、库存状态以及操作日志等数据,同时,可能还会运用Redis来缓存部分...
- 安全性:使用Spring Security进行权限控制和防止XSS、CSRF等攻击。 - 日志系统:如Log4j,记录系统运行日志,便于调试和监控。 通过分析这个压缩包中的"code-337",我们可以深入研究上述技术在实际项目中的应用...
同时,Spring Security则为系统提供了安全防护,确保数据的安全性。 Vue.js作为前端框架,以其轻量级、高性能和组件化的特性,极大地提高了开发效率。Vue.js的响应式数据绑定和虚拟DOM技术,使得用户界面的更新更为...
此外,还可以使用Spring Security等库进行权限控制,防止非法访问。 7. **日志记录**:利用Log4j或SLF4J等日志框架记录操作日志,便于系统维护和问题排查。 8. **单元测试与集成测试**:使用JUnit和Mockito等工具...