`
leman_zk
  • 浏览: 23496 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

【自学Spring Security】之添加数据库支持

    博客分类:
  • SSH
阅读更多

    上次编写了一个能够运行的Demo程序,但不是很符合实际,很少人将用户名和密码配置到文件当中去吧,今天想给这个Demo添加如下功能:
    1)用户名和密码要存在数据库当中;

    2)自定义登录界面;
    3)admin用户和user用户看到了index.jsp文件内容要不同,admin用户可以多看到一个admin.jsp的连接。
    好了,开始今天的程序,首先要添加MYSQL的jdbc驱动、commons-dbcp-1.4.jar、commons-pool-1.5.5.jar和org.springframework.transaction-3.0.6.RELEASE.jar(在Spring Security中没有提供,需要自己下载):
    一,从数据库中读取用户名和密码
    1.新建数据库表,数据库用的是MySQL
    user表

DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
  `username` varchar(50) NOT NULL,
  `password` varchar(50) NOT NULL,
  `enabled` tinyint(1) NOT NULL,
  PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('root', 'root', '1');
INSERT INTO `users` VALUES ('user', 'user', '1');

   authorities表

DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
  `username` varchar(50) NOT NULL,
  `authority` varchar(50) NOT NULL,
  KEY `fk_authorities_users` (`username`),
  CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of authorities
-- ----------------------------
INSERT INTO `authorities` VALUES ('root', 'ROLE_ADMIN');
INSERT INTO `authorities` VALUES ('user', 'ROLE_USER');
INSERT INTO `authorities` VALUES ('root', 'ROLE_USER');

   2.修改springContext-security.xml

   将

<authentication-manager>  
        <authentication-provider>  
            <user-service>  
                 <user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />  
                 <user name="user" password="user" authorities="ROLE_USER" />  
            </user-service>  
        </authentication-provider>  
</authentication-manager>

 替换为

<authentication-manager>
        <authentication-provider user-service-ref='myUserDetailsService'/>
</authentication-manager>

<beans:bean id="myUserDetailsService"  class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
</beans:bean>

   3.定义数据源(我是新建了一个springContext-business.xml文件,并并在web.xml的context-param中添加路径信息)

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost/test" />
        <property name="username" value="root" />
        <property name="password" value="root" />
</bean>

   现在再运行一下程序,可以了吧。

   现在还有一个问题:对于遗留系统,数据库的表是不能修改的,可以将myUserDetailsService 这个Bean修改为:

<beans:bean id="myUserDetailsService"  class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
        <beans:property name="dataSource" ref="dataSource"/>
        <beans:property name="usersByUsernameQuery" value="select username,password,enabled from users where username=?"/>
        <beans:property name="authoritiesByUsernameQuery" value="select username,authority from authorities where username=?"/>
</beans:bean>

    userByUsernameQuery传入用户名,返回username,password,enable三个字段,如果字段不匹配或者没有enable字段,可以写成:select name as username,pwd as password,1 from ....。

    authoritiesByUsernameQuery传入用户名,返回username和authority两个字段。

    二、自定义登录界面

    1.删除<http>标签,替换为

<http pattern="/login.jsp" security="none"/>
<http access-denied-page="/access_denied.jsp">
        <form-login login-page="/login.jsp"/>
        <intercept-url pattern="/admin.jsp" access="ROLE_ADMIN"/>
        <intercept-url pattern="/**" access="ROLE_USER"/>
        <session-management>
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
        </session-management>
</http>

    设置login.jsp所有人都可以访问

    2.新建login.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>
    <form action="j_spring_security_check" method="post">
        用户:<input type="text" name="j_username"/><br>
        密码:<input type="text" name="j_password"/><br>
        <input type="submit">
    </form>
</body>
</html>

    注意:j_spring_security_check,j_username,j_password都是Spring Security规定好的,不能改变。

   三,实现admin和user用户看到的页面不同

   这里要使用到Spring Security的标签库,并开启use-expressions。

   1.在http标签上添加user-expression="true"属性

<http pattern="/login.jsp" security="none"/>
    <http access-denied-page="/access_denied.jsp" use-expressions="true">
        <form-login login-page="/login.jsp"/>
        <intercept-url pattern="/admin.jsp" access="hasRole('ROLE_ADMIN')"/>
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')"/>
        <session-management>
            <concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
        </session-management>
</http>

    所有的access值也要使用内置的表达式hasRole来判断权限(注意括号内还有一对单引号)。

   2.修改index.jsp为

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>

<html>
  <head>
    <title>欢迎页面</title>
  </head>
  <body>
<h2>这是首页,欢迎:<sec:authentication property="name"/></h2>
<sec:authorize access="hasRole('ROLE_ADMIN')">
    <a href="admin.jsp">进入admin页面</a>
</sec:authorize>
  </body>
</html>

 

好了,今天就学习到这里吧。请高手多多指点,轻拍。

分享到:
评论
2 楼 leman_zk 2012-03-05  
pastore123 写道
问下,需要自己编写myUserDetailsService这个类吗?还有一个问题是登录表单是提交到哪呢?

myUserDetailsService只要是一个实现了UserDetailsService的类即可。
表单j_spring_security_check提交后,被DelegatingFilterProxy处理,进行权限验证。
1 楼 pastore123 2012-03-04  
问下,需要自己编写myUserDetailsService这个类吗?还有一个问题是登录表单是提交到哪呢?

相关推荐

Global site tag (gtag.js) - Google Analytics