spring security 视频3可不可以不经过登录页,后台直接完成登录认证

在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
把配置信息.loginPage注释掉使用自带的登录页面可以进行身份认证,但是我把登录页面抽出来单独访问的时候总是报403
配置信息:
public void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.antMatchers("/index.html").permitAll()
.formLogin()
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/loginValid")
.loginPage("/login")
.failureUrl("/login?error")
.permitAll()
.logout().permitAll();
使用post请求工具报错403:
请问应该如何配置才能正常认证呢,登录页面要和项目分离开
服务器上login.html code:
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
表单添加 csrf验证
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
遇到同样的问题
该答案已被忽略,原因:
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。Spring Security3
使用中心认证服务(CAS)进行单点登录
高级CAS配置
CAS认证框架提供了高级的配置和与CAS服务的数据交换。在本节中,我们将会介绍CAS集成的高级配置。在我们觉得重要的地方将会包含相关的CAS配置指令,但是要记住的是CAS配置是很复杂的并超出了本书的范围。
assertion中获取属性
在CAS服务器传递ticket校验结果时,可以将基于CAS认证时查询到的信息进行传递(给CAS服务)。这些信息以键值对的方式进行传递,并可以包含用户相关的任何数据。我们将会使用这个功能在CAS响应中传递用户的属性,包括GrantedAuthority信息。
CAS内部如何工作
在进入CAS配置之前,我们简单介绍CAS认证过程的标准行为。下图将会帮助你理解CAS与嵌入式LDAP服务器交互的配置步骤:
上图描述了CAS服务器内部的认证流程,如果你要实现Spring Security与CAS的集成,你可能要修改CAS服务器的配置。所以,理解CAS认证的整体流程如何工作是很重要的。
CAS服务器的org.jasig.cas.authentication.AuthenticationManager(不要与SpringSecurity的同名类相混淆)负责基于提供的凭证信息进行用户认证。与Spring Security很相似,实际的认证委托给了一个(或更多)实现了org.jasig.cas.authentication.handler.AuthenticationHandler接口的处理类(在Spring Security中对应的接口是AuthenticationProvider)。
最后,一个org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver用来将传递进来的安全实体信息转换成完整的org.jasig.cas.authentication.principal.Principal(类似于Spring Security中UserDetailsService实现所作的那样)。
尽管没有没有完整介绍CAS服务器的完整功能,但是这些也能够帮助你理解下面几个练习中的配置步骤。我们建议你阅读CAS的源码并学习网络上的文档,在JA-SIG CAS wiki上,地址为: 。
配置CAS连接嵌入式LDAP服务器
CAS默认配置的org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver并不允许我们在与Spring Security CAS集成时,传递回属性信息,所以我们建议使用一个允许我们这样做的实现。
一个很容易配置和使用的认证处理(尤其是你学习了前章中的LDAP练习)是org.jasig.cas.authentication.handler.AuthenticationHandler,它会与我们前章中的嵌入式LDAP服务器通信。在后文中,我们将会介绍配置CAS返回LDAP属性。
所有CAS的配置都会在CAS安装后的WEB-INF/deployerConfigContext.xml文件中,将会涉及到插入类声明到已经存在的配置文件片段中。
【如果这个文件的内容你感到熟悉,那是因为CAS使用Spring框架进行配置,就像JBCP Pets!如果你想深入了解这些配置是做什么的,我们建议你使用一个较好的IDE来方便的查看CAS的源码。记住在本节及其余所有章节中,我们提到的WEB-INF/deployerConfigContext.xml,指的是CAS安装环境中而不是JBCP Pets。】
首先,我们需要添加一个AuthenticationHandler来代替SimpleTestUsernamePasswordAuthenticationHandler,它将会试图绑定用户到LDAP上(就像我们在第九章:LDAP目录服务中做的那样)。AuthenticationHandler要放在authenticationManager
bean的authenticationHandlers属性中:
java代码:
&property name="authenticationHandlers"&
&!-- ... --&
&bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"&
&property name="filter" value="uid=%u" /&
&property name="searchBase" value="ou=Users,dc=jbcppets,dc=com" /&
&property name="contextSource" ref="contextSource" /&
不要忘记移除SimpleTestUsernamePasswordAuthenticationHandler,或者至少将其定义移到BindLdapAuthenticationHandler后面,否则你的CAS认证不会使用LDAP而是会使用这个默认实现。
你可能会意识到这个bean引用了一个contextSource bean——它定义了org.springframework.ldap.core.ContextSource实现,而CAS将会用它与LDAP交互(对,CAS也使用了Spring LDAP)。我们将会在文件的最后进行定义,如下:
java代码:
&bean id="contextSource" class="org.springframework.ldap.core.support.LdapContextSource"&
&property name="urls"&
&value&ldap:
&/property&
&property name="userDn"
value="uid=ldapadmin,ou=Administrators,ou=Users,dc=jbcppets,dc=com"/&
&property name="password" value="password"/&
&property name="baseEnvironmentProperties"&
&value&java.naming.security.authentication&/value&
&value&simple&/value&
&/property&
与我们配置Spring Security连接外部的(非嵌入式的)LDAP服务器很类似,CAS需要一个用户DN作为管理用户以首先绑定到LDAP目录上。在本例中,我们使用的管理员是在第九章的JBCPPets.ldif启动练习中定义的。URL
ldap://127.0.0.1:33389包含了端口33389,是Spring Security嵌入式LDAP服务器默认使用的。正如我们在第九章讨论的,在产品配置中,你可能更会使用LDAPS以确保CAS LDAP请求的安全。
最后,我们需要配置一个新的org.jasig.cas.authentication.principal.CredentialsToPrincipalResolver,它负责将用户提供的凭证(CAS已经使用BindLdapAuthenticationHandler进行了认证)转换成完整的org.jasig.cas.authentication.principal.Principal认证实体。你会发现在这个类中有很多配置选项,我们会将其略过,但是欢迎你深入了解CAS。
在CAS authenticationManager bean中的credentialsToPrincipalResolvers属性中,添加如下的内联bean定义:
java代码:
&property name="credentialsToPrincipalResolvers"&
&bean class="org.jasig.cas.authentication.principal.CredentialsToLDAPAttributePrincipalResolver"&
&property name="credentialsToPrincipalResolver"&
&bean class="org.jasig.cas.authentication.principal.UsernamePasswordCredentialsToPrincipalResolver" /&
&/property&
&property name="filter" value="(uid=%u)" /&
&property name="principalAttributeName" value="uid" /&
&property name="searchBase" value="ou=Users,dc=jbcppets,dc=com" /&
&property name="contextSource" ref="contextSource" /&
&property name="attributeRepository" ref bean="attributeRepository" /&
你会发现就像Spring Security LDAP配置,相同的行为也在CAS中存在即基于DN中的目录子树根据属性匹配搜索安全实体。
注意,我们还没有配置attributeRepository,它引用了org.jasig.services.persondir.IpersonAttributeDao的实现。CAS提供了默认的配置,包含了这个接口的简单实现org.jasig.services.persondir.support.StubPersonAttributeDao,这在LDAP属性的练习前是足够的(稍后会讲到)。
所以,现在我们已经在CAS中配置了基本的LDAP认证,你能够重启CAS,启动JBCP Pets(如果它没有在运行的话)并认证任何在第九章中使用的LDAP用户(用户名ldapguest,密码password就不错)。但是在返回应用时,你会看到一个丑陋的403访问拒绝页面,这是因为我们的AuthenticationUserDetailsService在数据库中没有找到LDAP用户。现在让我们来解决这个问题!
assertion中获取UserDetails
当首次建立CAS与Spring Security集成时,我们配置过UserDetailsByNameServiceWrapper,它会将CAS提供的用户名转换成UserDetails,这是提过使用我们引用的UserDetailsService对象(我们的例子中,就是JdbcDaoImpl)。现在CAS引用了LDAP服务器,我们可以使用LdapUserDetailsService就像我们在第九章结束时讨论的那样,功能就会好用了。
但是在这里,我们体验Spring Security CAS集成的另外一种能力,即从CAS assertion中填充UserDetails。这只需简单的将AuthenticationUserDetailsService实现切换至o.s.s.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService就可以了,它的工作就是读取CAS assertion、寻找特定的属性并将属性值与用户的GrantedAuthority进行匹配。假设assertion返回了一个名为role的属性。我们只需要在dogstore-base.xml中简单配置一个新的authenticationUserDetailsService
java代码:
&bean id="authenticationUserDetailsService"
class="org.springframework.security.cas.userdetails.GrantedAuthorityFromAssertionAttributesUserDetailsService"&
&constructor-arg&
&value&role&/value&
&/constructor-arg&
接下来,要添加一些小的调试功能来允许我们查询assertion中的内容。
为了辅助查询CAS返回给JBCP Pets应用的信息,我们修改AccountController以展现CAS登录用户的信息以及CAS为我们提供的用户信息。首先,我们添加一个简单的URL处理方法到AccountController中:
java代码:
@RequestMapping(value="/account/viewCasUserProfile.do",method=RequestMethod.GET)
public void showViewCasUserProfilePage(ModelMap model) {
final Authentication auth = SecurityContextHolder.getContext().getAuthentication();
model.addAttribute("auth", auth);
if(auth instanceof CasAuthenticationToken) {
model.addAttribute("isCasAuthentication", Boolean.TRUE);
接下来,我们要添加一个JSP,它会展现CasAuthenticationToken的一些信息,这个对象代表CAS认证过的用户。它会放在WEB-INF/views/account/viewCasUserProfile.jsp。
java代码:
&!-- Common Header and Footer Omitted --&
&h1&View Profile&/h1&
Some information about you, from CAS:
&li&&strong&Auth:&/strong& ${auth}&/li&
&li&&strong&Username:&/strong& ${auth.principal}&/li&
&li&&strong&Credentials:&/strong& ${auth.credentials}&/li&
&c:if test="${isCasAuthentication}"&
&li&&strong&Assertion:&/strong& ${auth.assertion}&/li&
&li&&strong&Assertion Attributes:&/strong&
&c:forEach items="${auth.assertion.attributes}" var="attr"&
${attr.key}:${attr.value}&br /&
&/c:forEach&
&li&&strong&Assertion Attribute Principal:&/strong& ${auth.assertion.principal}&/li&
&li&&strong&Assertion Principal Attributes:&/strong&
&c:forEach items="${auth.assertion.principal.attributes}" var="attr"&
${attr.key}:${attr.value}&br /&
&/c:forEach&
在账号首页添加一个简单的链接,在WEB-INF/views/account/home.jsp中:
java代码:
&h1&Welcome to Your Account&/h1&
&!-- omitted --&
&li&&a href="viewCasUserProfile.do"&View CAS User Profile&/a&&/li&
最后,在assertion属性认证好用之前,我们需要(临时的)将这个页面进行授权检查。(Finally, we'll have to (temporarily) disable authorization checks for this page, until we get assertion attribute-based authorization working. )要做到这样只需要简单调整dogstore-security.xml,所以任何具有GrantedAuthority的登录用户都能访问这个页面以及“My
Account”页面:
java代码:
&intercept-url pattern="/home.do" access="permitAll"/&
&intercept-url pattern="/account/home.do" access="!anonymous"/&
&intercept-url pattern="/account/view*Profile.do"
access="!anonymous"/&
&intercept-url pattern="/account/*.do" access="hasRole('ROLE_USER')"/&
在完成这些细小的UI更新后,重启JBCP Pets应用,并试图访问这个页面。你会发现在页面提供了很多assertion包含的信息。
匹配LDAP属性到CAS属性
最后一个揭开的谜底是需要我们匹配LDAP属性到CAS assertion中(包括我们希望在GrantedAuthority中包含的role属性)。
我们将会在CAS deployerConfigContext.xml中添加一点其它的配置。这些新的配置将会指导CAS怎样从CAS Principal对象到CAS IPersonAttributes对象匹配属性,而后者将会最终序列化为ticket校验的一部分。这个bean的配置应该替代同名的bean即attributeRepository。
java代码:
&bean id="attributeRepository"
class="org.jasig.services.persondir.support.ldap.LdapPersonAttributeDao"&
&property name="contextSource" ref="contextSource" /&
&property name="requireAllQueryAttributes" value="true" /&
&property name="baseDN" value="ou=Users,dc=jbcppets,dc=com" /&
&property name="queryAttributeMapping"&
&entry key="username" value="uid" /&
&/property&
&property name="resultAttributeMapping"&
&entry key="cn" value="FullName" /&
&entry key="sn" value="LastName" /&
&entry key="description" value="role" /&
&/property&
这个功能可能会很令人迷惑——本质上,这个类的目的将Principal与后端的LDAP目录进行匹配(这就是queryAttributeMapping属性,将Principal的username域与LDAP查询的uid属性相匹配)。提供的baseDN属性要使用LDAP进行查询(uid=ldapguest) ,并且属性要从匹配的条目进行读取。 匹配到Principal属性使用resultAttributeMapping属性中的键值对——我们将LDAP的cn和sn属性匹配到有意义的名字,而description属性匹配到role属性,而这个role属性就是GrantedAuthorityFromAssertionAttributesUserDetailsService要进行查找的。
造成这样的复杂性很大程度上是因为这个功能的一部分被另外一个项目进行了封装即Person Directory(http://www.ja-sig.org/wiki/display/PD/Home),它的目的是从多个源收集关于某个人的信息并集成到单个视图上。Person Directory的设计并没有直接关联到CAS服务器上,所以能够重用在其它应用中。这种设计选择的不足之处在于它会使得CAS集成的配置比预想的更复杂。
【一些CAS中已有的LDAP属性。我们可能愿意建立与第九章Spring Security LDAP相同类型的LDAP查询,即能够匹配Principal到一个完整的LDAP标识名,而后用这个DN来查询组信息(使用基本的uniqueMember属性到一个groupOfUniqueNames条目)。但是,CAS LDAP代码并没有这种灵活性,这就使得更复杂的LDAP匹配需要扩展CAS中的基本类。】
还是感到迷惑?我们承认这对我们来说也有些迷惑,因为在LDAP数据和CAS数据之间的来回交互中有不同的方式。CAS的邮件列表和社区wiki(http://www.ja-sig.org/wiki/display/CASUM/Home)是了解别人经验和与有知识的读者询问问题的好地方。
最后,返回CAS
assertion中的属性
遗憾的是,CAS 2.0协议并没有明确定义返回数据的标准格式。在CAS的JIRA缺陷跟踪系统中,有很多尝试实现这个功能,但是被拒绝了,因为CAS2.0是稳定的所以在最近并不会修改它。
也就是说,很多用户需要扩展CAS的响应来包含属性。最终,CAS到客户应用的ticket校验响应是通过一个JSP渲染的,所以很容易修改你的CAS安装来包含一个响应,这个响应符合Cas20ServiceTicketValidator的属性解析。在你的CAS部署中,编辑WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp,并添加以下内容:
java代码:
&cas:authenticationSuccess&
&cas:user&${fn:escapeXml(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.id)}&/cas:user&
&cas:attributes&
&c:forEach var="attr" items="${assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes}"
varStatus="loopStatus" begin="0"
end="${fn:length(assertion.chainedAuthentications[fn:length(assertion.chainedAuthentications)-1].principal.attributes)-1}" step="1"&
&cas:${fn:escapeXml(attr.key)}&${fn:escapeXml(attr.value)}&/cas:${fn:escapeXml(attr.key)}&
&/c:forEach&
&/cas:attributes&
这会产生如下的CAS响应格式:
java代码:
&cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas"&
&cas:authenticationSuccess&
&cas:user&ldapguest&/cas:user&
&cas:attributes&
&cas:FullName&LDAP Guest&/cas:FullName&
&cas:role&ROLE_USER&/cas:role&
&cas:LastName&Guest&/cas:LastName&
&/cas:attributes&
&/cas:authenticationSuccess&
&/cas:serviceResponse&
当这些修改完成并重启CAS和JBCP Pets,你应该能够用ldapguest登录并访问使用ROLE_USER保护的区域。另外,你应该看一下“View CAS Profile”页面,它展现了CAS assertion返回的属性。
【注意——我们可以看到LdapPersonAttributeDao.resultAttributeMapping提供的属性名被直接用到CAS响应的XML中。这意味着它们不能是任意的,必须符合XML元素命名规则(例如,不能包含空格)。如果你想修改这种行为,你可能需要比这里更复杂的JSP代码。】
干的漂亮——在这两个复杂的产品间有很多的配置工作。休息一下喝杯咖啡吧!
一些CAS开发人员选择的另一种方式是扩展Cas20ServiceTicketValidator(在Spring Security这一端)来对CAS返回的响应进行自定义的处理。
使用SAML 1.1进行替代的票据认证
SAML是一个标准的、跨平台的协议,它通过结构化的XML assertion进行身份校验。SAML被很多的产品所支持,包括CAS(实际上,我们将会在稍后的章节中看到Spring Security里面对SAML的支持)。
SAML的安全assertion XML语法解决了我们前面讲到的CAS响应协议传递属性的问题。令人高兴的是,切换CAS ticket校验和SAML ticket校验只需要修改dogstore-base.xml中的TicketValidator实现即可。添加一个bean如下:
java代码:
&bean id="samlTicketValidator" class="org.jasig.cas.client.validation.Saml11TicketValidator"&
&constructor-arg value="http://localhost:8080/cas/"/&
然后,替换CasAuthenticationProvider使用这个TicketValidator:
java代码:
&bean id="casAuthenticationProvider"
class="org.springframework.security.cas.authentication.CasAuthenticationProvider"&
&property name="ticketValidator" ref="samlTicketValidator"/&
&property name="serviceProperties" ref="casService"/&
重启JBCP Pets应用就会使用SAML响应进行ticket校验了。注意的是,CAS ticket响应并没有被Spring Security进行日志记录,所以你要么对JA-SIG CAS客户端类启用日志(在log4j中对org.jasig启用日志)要么使用调试查看响应的不同。
总之,建议使用SAML ticket校验而不是CAS 2.0 ticket校验,因为前者提供了更多的防治重造的功能,包括时间戳校验并以标准的方式解决了属性问题。
属性查询的用处
要记住的是CAS为我们的应用提供了一层抽象,移除了我们引用对用户存储的直接访问,作为替代所有这样的访问通过CAS作为代理来进行。
这个功能很强大!这意味着我们的应用不再关心用户在什么类型的存储中,也不用关心怎样访问它们的细节——只需与CAS确认一个用户有权限访问应用。对于系统管理员来说,这意味着,如果LDAP改名、转移位置或者修改的话,他们只需要在一个位置进行重新配置——CAS。通过CAS进行集中访问使得组织中安全架构更高级别的灵活性和适应性成为可能。
扩展这个话题到从CAS获取属性的用处——现在,所有通过CAS认证的应用对用户都有了相同的视角(译者注:即获取的信息是一致的),从而能够在任何使用CAS的环境下以一致的格式显示信息。
注意的是,一旦认证完成,Spring Security CAS不会再次查询CAS除非用户需要重新认证。这意味着,存储在应用本地用户Authentication对象中的属性和其它用户信息可能会失效且可能与CAS服务器不一致。注意要设置session的超时时间以避免这种潜在的问题。
其它的CAS功能
除了通过Spring Security CAS包装暴露出来的功能,CAS还提供了高级配置功能。其中一些如下:
对访问多个使用CAS安全的应用提供了透明的单点登录功能,这要在一个可配置(在CAS服务器端)的时间内。通过在TicketValidator中将renew属性设置为true,应用可以强制用户到CAS进行认证——你可能希望在自定义代码中有条件的设置这个属性,如当用户试图访问应用中高安全性的区域时;
为不能直接访问CAS的二级应用提供了ticket代理功能。当从CAS请求一个ticket时,web应用可能通过二级代理应用来请求授权ticket。关于这个的更多功能可以阅读CAS网站();
协调拥有活跃CAS session的多个参与应用间的单点登出(这不是通过Spring Security直接支持的,而是CAS客户端通过联合使用HttpSessionListener和servlet过滤器)。
我们建议你去探索CAS客户端和服务端的所有功能,并在JA-SIG社区论坛中向大家提问题。
在本章中,我们学习了中心认证服务(CAS)单点登录门户,以及它怎样与Spring Security集成,在本章中,我们学到了如下内容:
CAS架构以及在使用CAS的环境中各个参与角色的通信;
使用CAS的应用给开发人员和系统管理员带来的好处;
配置JBCP Pets与基本的CAS安装交互;
更新CAS与LDAP交互并实现LDAP与使用CAS的应用共享数据;
使用修改过的CAS 2.0协议和工业标准的SAML协议实现与CAS的属性 交换。
我们希望本章的内容是关于单点登录的一个有趣开端。在市场上还有很多其它的单点登录系统,它们中大多数是商用的,但是CAS在开源SSO领域无疑是领导者,并且是在任何组织中构建单点登录的绝佳平台。
在下一章中,我们将会转回标准认证,但是这次我们将会移除用户名和密码而是依赖一种新的认证机制。有趣吗?那就开始吧!
他的博客地址:
他的新浪微博:
本书源代码的地址:
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!博客分类:
使用Spring Security实现权限管理
1、技术目标
了解并创建Security框架所需数据表
为项目添加Spring Security框架
掌握Security框架配置
应用Security框架为项目的CRUD操作绑定权限
注意:本文所用项目为"影片管理",参看
2、权限管理需求描述
为系统中的每个操作定义权限,如定义4个权限: 1)超级权限,可以使用所有操作 2)添加影片权限 3)修改影片权限 4)删除影片权限
为系统设置管理员帐号、密码
为系统创建权限组,每个权限组可以配置多个操作权限,如创建2个权限组: 1)"Administrator"权限组,具有超级权限 2)"影片维护"权限组,具有添加影片、修改影片权限
可将管理员加入权限组,管理员登录后具备权限组所对应操作权限
管理员可不属于某权限组,可为管理员直接分配权限
3、使用准备
3.1)在数据库中创建6张表
管理员帐号表
t_role权限表
t_group_role权限组对应权限表
t_group_user管理员所属权限组表
t_user_role管理员对应权限表
建表SQL语句如下:
SET FOREIGN_KEY_CHECKS=0;
------------------------------
-- 创建管理员帐号表t_admin
-- ----------------------------
CREATE TABLE `t_admin` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`passwd` varchar(12) NOT NULL DEFAULT '' COMMENT '用户密码',
`nickname` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名字',
`phoneno` varchar(32) NOT NULL DEFAULT '' COMMENT '电话号码',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
-- ----------------------------
-- 添加3个管理帐号
-- ----------------------------
INSERT INTO `t_admin` VALUES ('1', 'admin', 'admin', '');
INSERT INTO `t_admin` VALUES ('4', '123456', 'test', '');
INSERT INTO `t_admin` VALUES ('5', '111111', '111111', '');
-- ----------------------------
-- 创建权限表t_role
-- ----------------------------
CREATE TABLE `t_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`role` varchar(40) NOT NULL DEFAULT '',
`descpt` varchar(40) NOT NULL DEFAULT '' COMMENT '角色描述',
`category` varchar(40) NOT NULL DEFAULT '' COMMENT '分类',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8;
-- ----------------------------
-- 加入4个操作权限
-- ----------------------------
INSERT INTO `t_role` VALUES ('1', 'ROLE_ADMIN', '系统管理员', '系统管理员');
INSERT INTO `t_role` VALUES ('2', 'ROLE_UPDATE_FILM', '修改', '影片管理');
INSERT INTO `t_role` VALUES ('3', 'ROLE_DELETE_FILM', '删除', '影片管理');
INSERT INTO `t_role` VALUES ('4', 'ROLE_ADD_FILM', '添加', '影片管理');
-- ----------------------------
-- 创建权限组表
-- ----------------------------
CREATE TABLE `t_group` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`groupname` varchar(50) NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- 添加2个权限组
-- ----------------------------
INSERT INTO `t_group` VALUES ('1', 'Administrator');
INSERT INTO `t_group` VALUES ('2', '影片维护');
-- ----------------------------
-- 创建权限组对应权限表t_group_role
-- ----------------------------
CREATE TABLE `t_group_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`groupid` bigint(20) unsigned NOT NULL,
`roleid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `groupid2` (`groupid`,`roleid`),
KEY `roleid` (`roleid`),
CONSTRAINT `t_group_role_ibfk_1` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
CONSTRAINT `t_group_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8;
-- ----------------------------
-- 加入权限组与权限的对应关系
-- ----------------------------
INSERT INTO `t_group_role` VALUES ('1', '1', '1');
INSERT INTO `t_group_role` VALUES ('2', '2', '2');
INSERT INTO `t_group_role` VALUES ('4', '2', '4');
-- ----------------------------
-- 创建管理员所属权限组表t_group_user
-- ----------------------------
CREATE TABLE `t_group_user` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`userid` bigint(20) unsigned NOT NULL,
`groupid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
KEY `groupid` (`groupid`),
CONSTRAINT `t_group_user_ibfk_2` FOREIGN KEY (`groupid`) REFERENCES `t_group` (`id`),
CONSTRAINT `t_group_user_ibfk_3` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
-- ----------------------------
-- 将管理员加入权限组
-- ----------------------------
INSERT INTO `t_group_user` VALUES ('1', '1', '1');
INSERT INTO `t_group_user` VALUES ('2', '4', '2');
-- ----------------------------
-- 创建管理员对应权限表t_user_role
-- 设置该表可跳过权限组,为管理员直接分配权限
-- ----------------------------
CREATE TABLE `t_user_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`userid` bigint(20) unsigned NOT NULL,
`roleid` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `userid` (`userid`),
KEY `roleid` (`roleid`),
CONSTRAINT `t_user_role_ibfk_1` FOREIGN KEY (`userid`) REFERENCES `t_admin` (`id`),
CONSTRAINT `t_user_role_ibfk_2` FOREIGN KEY (`roleid`) REFERENCES `t_role` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
3.2)在项目中新增如下jar包(security框架所需jar包):
注意:以下jar包本文已提供下载
spring-security-config-3.1.0.RC2.jar
spring-security-core-3.1.0.RC2.jar
spring-security-taglibs-3.1.0.RC2.jar
spring-security-web-3.1.0.RC2.jar
3.3)创建如下包,放置登录验证过滤器代码:
com.xxx.security
3.4)在src下创建Spring配置文件applicationContext-security.xml,内容如下:
&?xml version="1.0" encoding="UTF-8"?&
&beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"&
&!-- 这里进行配置 --&
&/beans:beans&
3.5)在web.xml中加入security配置,如下:
&?xml version="1.0" encoding="UTF-8"?&
&web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&
&welcome-file-list&
&welcome-file&index.jsp&/welcome-file&
&/welcome-file-list&
&context-param&
&param-name&contextConfigLocation&/param-name&
&param-value&/WEB-INF/applicationContext-*.xml,classpath*:applicationContext-*.xml&/param-value&
&/context-param&
&!-- 配置Spring Security --&
&filter-name&springSecurityFilterChain&/filter-name&
&filter-class&org.springframework.web.filter.DelegatingFilterProxy&/filter-class&
&filter-mapping&
&filter-name&springSecurityFilterChain&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
&filter-name&struts2&/filter-name&
&filter-class&org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter&/filter-class&
&filter-mapping&
&filter-name&struts2&/filter-name&
&url-pattern&/*&/url-pattern&
&/filter-mapping&
&listener&
&listener-class&org.springframework.web.context.ContextLoaderListener&/listener-class&
&/listener&
&/web-app&
4、站点根路径下创建登录页面login.jsp,代码如下:
&%@ page language="java" contentType="text/ charset=UTF-8"
pageEncoding="UTF-8"%&
&%@ taglib prefix="s" uri="/struts-tags"%&
&%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%&
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&meta http-equiv="Content-Type" content="text/ charset=utf-8" /&
&title&后台登录&/title&
&body onload="document.loginForm.j_username.focus();"&
&!-- 登录表单 --&
&form name="loginForm" action="&c:url value='/j_spring_security_check'/&" method="post"&
&!-- 登录失败后,显示之前的登录名 --&
用户名:&input type='text' name='j_username' class="txtinput"
value='&c:if test="${not empty param.login_error}" &
&c:out value="${SPRING_SECURITY_LAST_USERNAME}"/&&/c:if&' /&
密码:&input type='password' name='j_password' class="txtinput" /&
&input type="checkbox" name="_spring_security_remember_me" /&
&保存登录信息
&input name="submit" type="submit" value="提交" /&
&input name="reset" type="reset" value="重置" /&
&!-- 显示登录失败原因 --&
&c:if test="${not empty param.error}"&
&font color="red"& 登录失败&br /&
原因: &c:out value="${SPRING_SECURITY_LAST_EXCEPTION.message}" /&. &/font&
5、站点根路径下创建注销页面loggedout.jsp,代码如下:
&%@page session="false" %&
&%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&
&%@ page pageEncoding="UTF-8"%&
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&meta http-equiv="content-type" content="text/ charset=UTF-8" /&
&title&登出&/title&
你已经退出。
&a href="&c:url value='/login.jsp'/&"&点击这里登录&/a&
6、站点根路径下创建HttpSession超时提示页面timeout.jsp,代码如下:
&%@page session="false" %&
&%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&
&%@ page pageEncoding="UTF-8" contentType="text/ charset=UTF-8"%&
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+
&!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&
&html xmlns="http://www.w3.org/1999/xhtml"&
&title&用户失效&/title&
你的登录已经失效,请重新登录。
&a href="&c:url value='/login.jsp'/&" &
点击这里登录&/a&
7、在com.xxx.security包下创建登录验证过滤器,该过滤器可用于在管理员登录时进行日志记录等相关操作,包括两个类:
LoginUsernamePasswordAuthenticationFilter
LoginSuccessHandler
7.1)LoginUsernamePasswordAuthenticationFilter代码如下:
package com.xxx.
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationF
public class LoginUsernamePasswordAuthenticationFilter extends
UsernamePasswordAuthenticationFilter {
7.2)LoginSuccessHandler代码如下:
package com.xxx.
import java.io.IOE
import javax.servlet.ServletE
import javax.servlet.http.HttpServletR
import javax.servlet.http.HttpServletR
import org.springframework.security.core.A
import org.springframework.security.core.userdetails.UserD
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessH
* 处理管理员登录日志
public class LoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler{
public void onAuthenticationSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication authentication) throws IOException,
ServletException {
UserDetails userDetails = (UserDetails)authentication.getPrincipal();
//输出登录提示信息
System.out.println("管理员 " + userDetails.getUsername() + " 登录");
super.onAuthenticationSuccess(request, response, authentication);
8、在applicationContext-security.xml中加入权限管理配置,如下:
&?xml version="1.0" encoding="UTF-8"?&
&beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:b="http://www.springframework.org/schema/beans" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"&
&!-- 不拦截login.jsp --&
&intercept-url pattern="/login.jsp*" access="IS_AUTHENTICATED_ANONYMOUSLY" /&
&!--仅拦截到manager下面的内容,具备access对应权限的--&
&intercept-url pattern="/manager/**" access="ROLE_ADMIN,ROLE_UPDATE_FILM,ROLE_DELETE_FILM,ROLE_ADD_FILM" /&
&!-- 设置登录过滤器 --&
&custom-filter before="FORM_LOGIN_FILTER" ref="authenticationProcessingFilter" /&
&!-- 登录表单设置 --&
&form-login login-page="/login.jsp"
default-target-url="/manager/films.jsp"
authentication-failure-url="/login.jsp?error=true" /&
&!-- 登出操作后跳转到该页面 --&
&logout logout-success-url="/loggedout.jsp"
delete-cookies="JSESSIONID" /&
&remember-me /&
&!-- SESSION超时后跳转到该页面 --&
&session-management invalid-session-url="/timeout.jsp"&
&/session-management&
&authentication-manager alias="authenticationManager"&
&authentication-provider&
直接使用SQL语句查询登录帐号对应权限,
users-by-username-query:查询登录用户是否存在
authorities-by-username-query:查询登录用户权限(登录用户可以不属于任何组,从t_user_role表中获取权限)
group-authorities-by-username-query:查询登录用户所在组的权限
&jdbc-user-service data-source-ref="dataSource"
group-authorities-by-username-query="SELECT g.id,g.groupname,role.role
FROM t_group AS g
LEFT OUTER JOIN t_group_role AS grouprole ON (g.id = grouprole.groupid)
LEFT OUTER JOIN t_role AS role ON (role.id = grouprole.roleid)
LEFT OUTER JOIN t_group_user AS groupuser on (g.id = groupuser.groupid)
LEFT OUTER JOIN t_admin ON (t_admin.id = groupuser.userid)
WHERE t_admin.nickname = ?"
users-by-username-query="SELECT t_admin.nickname AS username,t_admin.passwd as password,'true' AS enabled
FROM t_admin
WHERE t_admin.nickname = ?"
authorities-by-username-query="SELECT t_admin.nickname AS username,role.role as authorities
FROM t_admin
LEFT OUTER JOIN t_user_role AS userrole ON(t_admin.id = userrole.userid)
LEFT OUTER JOIN t_role AS role ON (userrole.roleid = role.id)
WHERE t_admin.nickname = ?" /&
&/authentication-provider&
&/authentication-manager&
&!-- 自定义消息 --&
&b:bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"&
&b:property name="basename"
value="classpath:org/springframework/security/messages" /&
&!-- 定制登录过滤器 --&
&beans:bean id="loginSuccessHandler" class="com.xxx.security.LoginSuccessHandler"&
&b:property name="defaultTargetUrl"&
&!-- 登录成功后转发到该页面 --&
&b:value&/manager/films.jsp&/b:value&
&/b:property&
&/beans:bean&
&beans:bean id="authenticationProcessingFilter" class="com.xxx.security.LoginUsernamePasswordAuthenticationFilter"&
&beans:property name="authenticationSuccessHandler" ref="loginSuccessHandler"&&/beans:property&
&beans:property name="authenticationFailureHandler" ref="authenticationFailureHandler"&&/beans:property&
&beans:property name="authenticationManager" ref="authenticationManager"&&/beans:property&
&/beans:bean&
&beans:bean id="authenticationFailureHandler" class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler"&
&beans:property name="defaultFailureUrl"&
&!-- 登录失败后转发到该页面 --&
&beans:value&/login.jsp?error=true&/beans:value&
&/beans:property&
&/beans:bean&
&/beans:beans&
9、为影片页面films.jsp定制操作权限,定制后,不同的帐号登录会看到不同的操作,
比如,帐号"admin"属于权限组"Administrator",具备权限"ROLE_ADMIN",登录后
可以看到所有操作,帐号"test"属于权限组"影片维护",具备权限"ROLE_UPDATE_FILM"
和"ROLE_ADD_FILM",登录后只能看到"添加影片信息"和"修改"操作
films.jsp页面权限分布图:
films.jsp代码如下:
&%@ page language="java" contentType="text/ charset=utf-8"
pageEncoding="utf-8" %&
&%@taglib uri="/struts-tags" prefix="s" %&
&%@ taglib prefix="security"
uri="http://www.springframework.org/security/tags"%&
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
&!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&
&title&信息操作&/title&
&s:form action="/film/findFilm" method="post"&
&s:submit value=" 获取所有影片信息 "&&/s:submit&
&!-- 添加影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_ADD_FILM权限可以执行 --&
&security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_ADD_FILM"&
&a href="&%=basePath %&manager/insertFilm.jsp"&添加影片信息&/a&&br /&
&/security:authorize&
&s:if test="filmList != null"&
&table border="1" width="40%"&
&th&序号&/th&&th&影片名&/th&&th&操作&/th&
&%-- 遍历影片信息 --%&
&s:iterator var="film" value="filmList" status="st"&
&td&&s:property value="#st.index+1" /&&/td&
&td&&s:property value="fname" /&&/td&
&!-- 修改影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_UPDATE_FILM权限可以执行 --&
&security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_UPDATE_FILM"&
&s:url id="detailUrl" value="/film/detailFilm"&
&s:param name="id" value="%{id}"/&
&s:a href="%{detailUrl}"&[修改]&/s:a&&
&/security:authorize&
&!-- 删除影片操作,登录帐号具备ROLE_ADMIN权限或者ROLE_DELETE_FILM权限可以执行 --&
&security:authorize ifAnyGranted="ROLE_ADMIN,ROLE_DELETE_FILM"&
&s:url id="deleteUrl" value="/film/deleteFilm"&
&s:param name="id" value="%{id}"/&
&s:a href="%{deleteUrl}"&[删除]&/s:a&
&/security:authorize&
&/s:iterator&
(670.9 KB)
下载次数: 1630
浏览 204749
浏览: 443028 次
来自: 成都
现在新推出了一个权限框架,叫jCasbin(https://g ...
过来学习,结合楼主的分享,自己试一试,谢谢分享
布置好了项目和数据库弄好了,但是登录就报这个错org.spri ...
请问使用ajax之后那个spring security的权限管 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 spring security 视频 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信