spring security demo入门分析(转)
要学习spring security 我个人的学习步骤是首先运行一个demo,让自己有个感性认识,上一篇文章已经介绍过了,在此就不介绍了。
然后分析demo工作包括哪些包,每个包什么作用,然后分析原理和验证流程,最后详细研究配置文件等内容。
下面就是对源码分析的过程。
spring security 包内容:
Core-spring-security-core.jar
包含了核心认证和权限控制类和接口, 提供核心的程序支持和最基本的API。是使用Spring Security所必须使用的。支持单独运行的应用, 提供远程客户端,方法(服务层)的安全和JDBC用户验证。包含顶级包:
-
org.springframework.security.core
-
org.springframework.security.access
-
org.springframework.security.authentication
-
org.springframework.security.provisioning
-
org.springframework.security.remoting
包含过滤器和对应的web安全架构代码。在需要任何依赖servlet API的地方你将需要它。如果你需要Spring Security Web认证服务和基于URL的权限控制,请使用它。 他的主包是org.springframework.security.web
。
包含安全命名控制解析代码(因此我们不能直接把它用在你的应用中)。 如果使用了Spring Security XML命名控制来进行配置的时候需要使用。它的主包是org.springframework.security.config
。
LDAP认证和实现代码,如果你需要使用LDAP认证或管理LDAP用户实体就是必须的。 它的顶级包是org.springframework.security.ldap
。
处理领域对象ACL实现。用来提供安全特定的领域对象实例,在你的应用中。它的 顶级包是org.springframework.security.acls
。
Spring Security的CAs客户端集成。如果你希望使用Spring Security web认证 整合一个CAS单点登录服务器。它的顶级包是 org.springframework.security.cas
。
OpenID - spring-security-openid.jar
OpenID web认证支持。用来认证用户,通过一个外部的OpenID服务。 org.springframework.security.openid
。需要OpenID4Java。
crypto spring-security-crypto-3.1.0.RELEASE.jar
加密相关的包,它的顶级包是org.springframework.security.crypto
remoting spring-security-remoting-3.1.0.RELEASE.jar
远程客户端相关的包,主要包括dns、rmi、httpinvoker。它的顶级包是org.springframework.security.remoting
taglibs spring-security-taglibs-3.1.0.RELEASE.jar
demo说明
根据官方文档spring-security-samples-tutorial- 3.1.0.RELEASE.war是进行spring security的最基础的文档,于是就对这个工程进行了分析。引入了工程后,发现代码确实很少,jsp也很少就6个非常简单的jsp,然后通过 tomcat运行,效果也很简单。
运行后发现一个很奇怪的现象就是找不到登录页,下图就是默认的home页面。
点击Secure page后会进入登录页面,但是这个页面在代码里面是找不到的,为了这个问题,我研究了好一会才发现登录页面的位置。
<http use-expressions="true">
<!--下面两句表示在访问下面配置的资源的时候需要身份验证,如果没有身份验证跳转到登录页面-->
<intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')"/>
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<intercept-url pattern="/**" access="permitAll" />
<!--下面一句表示登录页面的配置选项,默认登录页就是上面由DefaultLoginPageGeneratingFilter生成的页面
默认跳转地址为/j_spring_security_check-->
<form-login />
<logout logout-success-url="/loggedout.jsp" delete-cookies="JSESSIONID"/>
<remember-me />
<session-management invalid-session-url="/timeout.jsp">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
</session-management>
</http>
isAuthenticated()定义的位置如下:
在spring-security-core
.jar中定义的接口
public interface Authentication extends Principal, Serializable {
Collection<GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated)throws IllegalArgumentException;
}
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
}
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
// Place the last username attempted into HttpSession for views
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
}
// Allow subclasses to set the "details" property
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
用户信息的配置是放在配置文件applicationContext-security.xml中的,关键配置项为:
<authentication-provider>
<password-encoder ref="encoder"/>
<user-service>
<user name="rod" password="4efe081594ce25ee4efd9f7067f7f678a347bccf2de201f3adf2a3eb544850b465b4e51cdc3fcdde" authorities="supervisor, user, teller" />
<user name="dianne" password="957ea522524a41cbfb649a3e293d56268f840fd5b661b499b07858bc020d6d223f912e3ab303b00f" authorities="user,teller" />
<user name="scott" password="fb1f9e48058d30dc21c35ab4cf895e2a80f2f03fac549b51be637196dfb6b2b7276a89c65e38b7a1" authorities="user" />
<user name="peter" password="e175750688deee19d7179d444bfaf92129f4eea8b4503d83eb8f92a7dd9cda5fbae73638c913e420" authorities="user" />
</user-service>
</authentication-provider>
</authentication-manager>
最后想说的就是框架其实只是用来快速开发用的,很多框架基本上都封装了实现的细节,我们 只知道怎么用是远远不够的,那样干的只是体力活,更多的我们应该去知道它为什么这么用,怎么实现的,然后我们可以不用框架,也可以写出很好的代码。其实说 白了,我们最需要掌握的就是解决问题的能里,能不是去跟别人说我会用什么什么框架之类的!