Spring Security教程(四)

在前面三个博客的例子中,登录页面都是用的Spring Security本身提供的,这明显不符合实际开发场景,同时也没有退出和注销按钮,所以在每次测试的时候都要经过关闭浏览器来注销达到清除session的效果。html

自定义页面

login.jsp:java

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>自定义登录页面</title>
</head>
<body>
    <div class="error ${param.error == true ? '' : 'hide'}">
        登录失败<br>
        ${sessionScope['SPRING_SECURITY_LAST_EXCEPTION'].message}
    </div>
    <form method="post" action="${pageContext.request.contextPath}/j_spring_security_check" style="width:260px; text-align: center">
        <fieldset>
            <legend>登录</legend>
            用户: <input type="text" name="j_username" style="width: 150px;"
                value="${sessionScope['SPRING_SECURITY_LAST_USERNAME']}" /><br />
            密码: <input type="password" name="j_password" style="width: 150px;" /><br />
            <input type="checkbox" name="_spring_security_remember_me" />两周以内没必要登录<br />
            <input type="submit" value="登录" /> <input type="reset" value="重置" />
        </fieldset>
    </form>
 
</body>
</html>复制代码

说明:特别要注意的是form表单的action是提交登录信息的地址,这是security内部定义好的,同时自定义form时,要把form的action设置为/jspringsecurity_check。注意这里要使用绝对路径,避免登录页面存放的页面可能带来的问题。jusername,输入登录名的参数名称,jpassword,输入密码的参数名称,这两个正常状况下也不会修改。mysql

springsecurityrememberme,选择是否容许自动登陆的参数名称。能够直接把这个参数设置为一个checkbox,无需设置value,Spring Security会自行判断它是否被选中,这也是security内部提供的,只须要配置,不须要本身实现。spring

配置制定的页面

配置文件以下:sql

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    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/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                        http://www.springframework.org/schema/security
                        http://www.springframework.org/schema/security/spring-security.xsd">
    
    <!-- <http pattern="/login.jsp" security="none"></http> -->
    <http auto-config="false">
        <intercept-url pattern="/login.jsp" access="IS_AUTHENTICATED_ANONYMOUSLY" />
        <intercept-url pattern="/adminPage.jsp" access="ROLE_ADMIN" />
        <intercept-url pattern="/**" access="ROLE_USER" />
        <form-login login-page="/login.jsp" default-target-url="/index.jsp"
            authentication-failure-url="/login.jsp?error=true" />
        <logout invalidate-session="true"
              logout-success-url="/login.jsp"
              logout-url="/j_spring_security_logout"/>  
    </http>
    <!-- 数据源 -->
    <beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <!-- 此为c3p0在spring中直接配置datasource c3p0是一个开源的JDBC链接池 -->
        <beans:property name="driverClass" value="com.mysql.jdbc.Driver" />
 
        <beans:property name="jdbcUrl"
            value="jdbc:mysql://localhost:3306/springsecuritydemo?useUnicode=true&characterEncoding=UTF-8" />
        <beans:property name="user" value="root" />
        <beans:property name="password" value="" />
        <beans:property name="maxPoolSize" value="50"></beans:property>
        <beans:property name="minPoolSize" value="10"></beans:property>
        <beans:property name="initialPoolSize" value="10"></beans:property>
        <beans:property name="maxIdleTime" value="25000"></beans:property>
        <beans:property name="acquireIncrement" value="1"></beans:property>
        <beans:property name="acquireRetryAttempts" value="30"></beans:property>
        <beans:property name="acquireRetryDelay" value="1000"></beans:property>
        <beans:property name="testConnectionOnCheckin" value="true"></beans:property>
        <beans:property name="idleConnectionTestPeriod" value="18000"></beans:property>
        <beans:property name="checkoutTimeout" value="5000"></beans:property>
        <beans:property name="automaticTestTable" value="t_c3p0"></beans:property>
    </beans:bean>
    
    <authentication-manager>
           <authentication-provider>
               <jdbc-user-service data-source-ref="dataSource"
                   users-by-username-query="select username,password,status as enabled from user where username = ?"
                   authorities-by-username-query="select user.username,role.name from user,role,user_role 
                                       where user.id=user_role.user_id and 
                                       user_role.role_id=role.id and user.username=?"/>
           </authentication-provider>
    </authentication-manager>
</beans:beans>复制代码

说明:express

  • form-login这个标签是配置登录页面的,其中的属性login-page是配置登录页面的,default-target-url配置登录成功后跳转到的页面,authentication-failure-url配置认证失败后的跳转页面。
  • 在上面的配置中,登录页面确定是不能拦截的,任何人都应该能够访问, 配置表示容许匿名用户访问,就是不用身份均可以访问;还有另外一种配置方式: ,这种配置达到的目的都是同样的。
  • logout这个标签用来配置退出或者注销,其中的属性invalidate-session,配置否是要清除session,logout-success-url配置注销成功后的跳转页面,logout-url提交退出或者注销的地址,所以咱们在配置退出或者注销的时候,只须要将url设置为/jspringsecurity_logout便可,这个地址也是security内部实现了的。
  • form-login标签中还有一个特别要注意的属性use-expressions,若是设置为true,这配置access就要作相应的改变,不然项目启动的时候会报错,错误以下:

file

  • 若是use-expressns="true"时,则表示改成 SpEL 表达式。 SpEL 容许使用特定的访问控制规则表达式语言。与简单的字符串如 ROLE_USER 不一样,配置文件能够指明表达式语言触发方法调用、引用系统属性、计算机值等等。http标签中的配置改成以下:
<http auto-config="false" use-expressions="true">
        <intercept-url pattern="/login.jsp" access="permitAll" />
        <intercept-url pattern="/adminPage.jsp" access="hasRole('ROLE_ADMIN')" />
        <intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
        <form-login login-page="/login.jsp" default-target-url="/index.jsp"
            authentication-failure-url="/login.jsp?error=true" />
        <logout invalidate-session="true"
              logout-success-url="/login.jsp"
              logout-url="/j_spring_security_logout"/>  
    </http>复制代码


配置文件中的其余配置在前面几篇博客中都有详细的讲解,这里就不赘述了。浏览器

其余文件

index.jsp微信

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>this is a user page</h1>
    <a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登录</a>
</body>
</html>复制代码

adminPage.jspsession

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <h1>this is a admin page</h1>
    <a href="${pageContext.request.contextPath}/j_spring_security_logout">退出登录</a>
</body>
</html>复制代码

这里定义了两个页面,index.jsp用户和管理员均可以访问,adminPage.jsp只有管理员能够访问,同时两个页面都有注销按钮,注销按钮提交的地址也就是上面配置文件中的地址/jspringsecurity_logout。pom.xml和前面的同样,这里就不贴了。jsp

结果

file

当输入普通用户的用户名和密码,同时勾选2周不用登录后,由于adminPage.jsp页面要有管理员权限才能访问,因此普通用户访问失败,index.jsp页面就能够访问;这时关闭页面后,再次访问资源,由于勾选了2周不用登录,因此能够成功访问;可是当点击退出登陆后,再次访问是就会跳转到登录页面,要求登录才能访问。

file

当输入管理员名和密码,同时勾选2周不用登录,验证成功后,跳转到index.jsp,同时adminPage.jsp也能够访问,这时把一个页面关闭再从新访问资源时,由于勾选2周不用登录,因此能够成功访问;而后注销,这是再访问资源时,就会跳转到登录页面,要求登录才能访问。微信公众号关注:ByteZ,获取更多学习资料

file

相关文章
相关标签/搜索