BSTEK Development Framework2(BDF2) : 3.1.替换登录页面

      BDF2提供的默认登录页面如下:

      可以用简单和简陋两个词来形容,之所以这样,是因为我们在设计之初就考虑程序员在使用的时候可能90%以上都会用自己的登录页面将其替换,所以就没做那么花哨,总的来说,BDF2当中很多功能用户都可以替换,替换的方法和理论多数都是一样的,那就是通过在WEB-INF/dorado-home/configure.propertie文件中覆盖对应的属性值,替换登录页面就是采用这种套路。

      当用户在访问一个需要用户信息的页面时,系统就会自动跳转到登录页面,要求用户登录,这个页面地址取自一个名为“bdf2.formLoginUrl”的属性值,这个值默认为/bdf2.core.view.frame.Login.d,也就是上图展示的页面。同样,如果我们要采用自己的登录页面,方法就是在WEB-INF/dorado-home/configure.propertie文件中,重新为bdf2.formLoginUrl属性指定一个新的URL即可。

      比如,我们这里为bdf2.formLoginUrl属性指定的URL为/login.jsp,同时设置bdf2.loginFailureTargetUrl属性值也是/login.jsp(登录失败后跳转的页面,这里表示登录失败后还是跳转到我们这里的login.jsp),这就表示我们将采用web应用根目录下的一个名为login.jsp的页面作为系统的登录页面,该页面代码如下:

login.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>用户登录</title>
</head>
<body>
<h1>登录</h1>
<form action="security_check_" method="post">
	用户名:<input type="text" name="username_"><br>
	密码:<input type="password" name="password_"><br>
	<input type="submit" value="登录">
</form>
</body>
</html>

      熟悉HTML的程序员都知道,这个页面非常简单,只有一个form表单,这个form表单action属性值为"security_check_",表示我们的表单将提交到这个URL,之前我们提过,登录处理页面的URL实际上由一个名为bdf2.loginProcessUrl的属性决定,而这个属性的默认值为/security_check_,所以如果你修改了这个属性,那么这里的action值就应该是你修改后的值;最后设置form的method属性为post,这个很重要,对于BDF2来说,处理登录登录,只接受post过来的请求,也就是说如果你不为form设置method属性(默认为get)或设置method属性值为get,这个处理登录请求的URL是不会处理的,原因很简单,因为get方式请求你的username与password就会被拼装在URL后面,毫无安全性可言了。

      在这个form表单里,我们设置了两个文本域:一个是用户名,一个是密码。这里需要注意的是用户名文本域的name值一定要是username_,密码一定要是password_,否则处理登录的URL将无法获取提交的用户名、密码信息。

      再次运行系统,选择登录,就可以看到我们刚才定义的登录页面login.jsp,输入注册的用户名,密码,发现登录不了,同时也没有任何错误消息,为了知道究竟出了什么样的错误,我们需要进一步修改我们的login.jsp,添加登录失败后的错误消息显示功能,修改好的login.jsp代码如下:

 

 

 

new login.jsp
<%@page import="org.apache.commons.lang.StringUtils"%>
<%@page import="org.springframework.security.web.WebAttributes"%>
<%@page import="com.bstek.bdf2.core.context.ContextHolder"%>
<%@ 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>
<h1>登录</h1>
<%!
private String getAuthenticationExceptionMessage(){
	Exception exp=(Exception)ContextHolder.getHttpSession().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
	if(exp==null){
		exp=(Exception)ContextHolder.getRequest().getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
	}
	if(exp!=null){
		return exp.getMessage();
	}
	return null;
	
}
%>
<%
String error=getAuthenticationExceptionMessage();
if(StringUtils.isNotEmpty(error)){
	out.println("Login Error:"+error);	
}
%>
<form action="security_check_" method="post">
	用户名:<input type="text" name="username_"><br>
	密码:<input type="password" name="password_"><br>
	<input type="submit" value="登录">
</form>
</body>
</html>

 

      我们添加了从环境中取错误消息的代码块,具体这里就不再解释了。再次运行输入用户名密码,点击登录,可以看到如下图所示的带提示错误消息的登录页面。

      从错误消息当中我们得知,原来登录是需要验证码的,如果我们希望登录不要检测验证码该怎么办呢?方法还是添加属性,我们在WEB-INF/dorado-home/configure.propertie文件中添加一名为bdf2.useCaptchaForLogin属性,通过之前的属性列表中描述我们得知,它的作用就是决定在登录时是否检查验证码的,它默认值为true,表示需要检查,所以才出现上图的错误,这里我们设置bdf2.useCaptchaForLogin=false,再次运行应用,输入账号信息登录,可以看到能正常进行主界面啦。

      这个时候,可能有些程序在想,如果我在登录的时候需要验证码又该如何处理呢?

      如果登录的时候,需要启用验证码,那就要在你的登录页面中添加验证码,从前面的属性描述表中我们得知,生成验证码图片的地址由名为bdf2.generateCaptchaUrl的属性决定,这个属性默认值为/generate.captcha,所以可以修改我们的登录表单,添加验证码图片,修改后的表单代码如下:

 

 

添加验证码
<form action="security_check_" method="post">
	用户名:<input type="text" name="username_"><br>
	密码:<input type="password" name="password_"><br>
	验证码:<input type="text" name="captcha_"><img src="generate.captcha.action?width=150&height=60"><br>
	<input type="submit" value="登录">
</form>

 

 

      上述代码当中,我们添加了一个名为loginCaptch的文本域,同时添加了一个用于显示验证码图片的img标记,这个img的src属性值为:generate.captcha.action?width=120&height=50&key=loginCaptch,这个地址当中generate.captcha为bdf2.generateCaptchaUrl的属性指定,需要注意的是它以.action结尾,后面我们会提到,这个.action结尾的URL是BDF2中提供的了一种简单实用的Controller的URL地址,URL后面有两个参数分别用于指定图片的宽度和高度,修改我们之前设置的bdf2.useCaptchaForLogin属性值为true。再次运行我们的系统,点击登录,可以看到如下效果的登录页面:

      输入用户名、密码及验证码就可以成功登录了。

      某些情况下,我们可能需要在登录的时候让在浏览器的cookie当中记录我们的登录信息(这个功能在某些论坛或购物网站中出现的频率比较高),BDF2同样提供了这种功能的支持,再次修改我们的登录表单,添加登录记忆功能,修改好的表单代码如下:

添加自动登录功能的登录表单
<form action="security_check_" method="post">
	用户名:<input type="text" name="username_"><br>
	密码:<input type="password" name="password_"><br>
	验证码:<input type="text" name="captcha_"><img src="generate.captcha.action?width=150&height=60"><br>
	自动登录:<input type="checkbox" name="remember_me_"><br>
	<input type="submit" value="登录">
</form>

      我们添加了一个checkbox,并且它的名字是"remember_me_",这样在登录的时候勾上这个checkbox,登录成功以后,关掉浏览器,然后再打开浏览器,输入主界面地址,可以看到系统不再弹出登录页面,直接成功登录了。

      好了,登录页面的扩展功能就是这些,其它的诸如美化的工作程序员可以自己考虑灵活添加,这里就不再赘述了。

图片等资源的采用

在自定义登录界面时,如果需要采用一些图片之类的资源,且将图片资源放在了web应用的根的某个目录下,那么需要通过设置以允许这些资源在不登录的情况下就可以访问,设置方法是打开我们的dorado-home/datasources.xml文件,在其中添加如下配置即可:

<bdf:anonymous-url urlPattern="/images/*.jpg"/>

上述配置就标明位于web应用的根的images目录下所有以.jpg结尾的文件可以在不登录情况下访问,如果要设置其它的资源也可以采用类似方式,如果有其它多种类型文件,那么就多加几条这个配置即可。需要注意的是,对于Java来说文件名后缀是区分大小写的,所以这里在以文件名后缀来判断是否可以匿名访问时需要注意大小写。


默认首页指定

如果你希望系统实现几个不同的登录页面,不同的登录页面登录后指向不同的默认首页,则解决办法是:

  1. 设置bdf的bdf2.loginSuccessAlwaysUseDefaultTargetUrl设置为false;

  2. 登录页面的action添加一个loginSuccessUrl参数,并自定义登录成功后的调整页面;


Attachments:

login.png (image/png)
login-fail.png (image/png)
login-with-captch.png (image/png)