Struts 2での認証コードの実装

9362 ワード

プロジェクトでは検証コード機能が使用されるため,実装後は後で使用するためにここに記録して実装コードを実現する.
まずはアクション
UserLoginVerificationCodeActionImpl.java
 
package action.impl;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.servlet.http.HttpSession;

import system.SysAction;
import tool.ImageCode;
import tool.RandomCodeImage;

public class UserLoginVerificationCodeActionImpl extends SysAction implements
		UserLoginVerificationCodeAction {

	private String code;

	private ByteArrayInputStream inputStream;

	private static final long serialVersionUID = 123456756789765L;

	/**
	 * @return the code
	 */
	public String getCode() {
		return code;
	}

	/**
	 * @return the inputStream
	 */
	public ByteArrayInputStream getInputStream() {
		return inputStream;
	}

	/**
	 * @param code
	 *            the code to set
	 */
	public void setCode(String code) {
		this.code = code;
	}

	/**
	 * @param inputStream
	 *            the inputStream to set
	 */
	public void setInputStream(ByteArrayInputStream inputStream) {
		this.inputStream = inputStream;
	}

	/**
	 *      
	 */
	public String verificationCode() {
		try {
			ImageCode imageCode = RandomCodeImage.getImage();
			HttpSession session = request.getSession();
			session.setAttribute("userLoginCode", imageCode.getKey());
			inputStream = imageCode.getValue();
			return SUCCESS;
		} catch (IOException e) {
			e.printStackTrace();
			return ERROR;
		}
	}

}

 
 ツールクラスImageCode.javaは、主にインタフェースを実現し、検証コードと生成された検証コードのバイト入力ストリームを記録する.
 
package tool;

import java.io.ByteArrayInputStream;
import java.util.Map.Entry;

public class ImageCode implements Entry<String, ByteArrayInputStream> {
	private String key;
	private ByteArrayInputStream value;

	public ImageCode(String key, ByteArrayInputStream byteArrayInputStream) {
		this.key = key;
		this.value = byteArrayInputStream;
	}

	public String getKey() {
		// TODO Auto-generated method stub
		return key;
	}

	public ByteArrayInputStream getValue() {
		// TODO Auto-generated method stub
		return value;
	}

	public ByteArrayInputStream setValue(ByteArrayInputStream value) {
		this.value = value;
		return value;
	}

}

 
 ツールクラスRandomCodeImage.javaは、主に検証コードと検証コード入力ストリームを生成します.
 
package tool;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;

public class RandomCodeImage {

	public static ImageCode getImage() throws IOException {

		Random random = new Random();

		int width = 60, height = 20;

		BufferedImage image = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		//   Graphics  ,      
		Graphics g = image.getGraphics();
		//          ,  Graphics        。
		g.setColor(Color.WHITE);
		//          
		g.fillRect(0, 0, width, height);
		//           
		g.setFont(new Font("Times New Roman", Font.PLAIN, 14));

		//        :            
		g.setColor(Color.WHITE);

		// //          155   ,             
		// for (int i = 0; i < 155; i++) {
		// int x = random.nextInt(width);
		// int y = random.nextInt(height);
		// int xl = random.nextInt(12);
		// int yl = random.nextInt(12);
		// g.drawLine(x, y, x + xl, y + yl);
		// }

		//         ,     ,   
		// String[] s = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
		// "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
		// "X", "Y", "Z" };
		String[] s = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" };
		String content = "";
		for (int i = 0; i < 4; i++) {
			String rand = "";
			if (random.nextBoolean()) {
				rand = String.valueOf(random.nextInt(10));
			} else {
				int index = random.nextInt(10);
				rand = s[index];
			}
			content += rand;
			g.setColor(Color.RED);
			g.drawString(rand, 13 * i + 6, 16);
		}

		//                      ,      
		g.dispose();

		ByteArrayOutputStream output = new ByteArrayOutputStream();
		ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);

		ImageIO.write(image, "JPEG", imageOut);

		imageOut.close();
		return new ImageCode(content, new ByteArrayInputStream(
				output.toByteArray()));
	}

	private static Color getRandColor(int fc, int bc) {
		Random random = new Random();
		if (fc > 255)
			fc = 255;
		if (bc > 255)
			bc = 255;
		int r = fc + random.nextInt(bc - fc);
		int g = fc + random.nextInt(bc - fc);
		int b = fc + random.nextInt(bc - fc);
		return new Color(r, g, b);
	}

}

 
 これがactionのプロファイルで、フロントページにアクセスできます.
conse.xml
 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
	<package name="userAdmin" namespace="/admin/userAdmin" extends="userAdminNLticket">	
	<action name="code" class="userLoginVerificationCodeAction"
			method="verificationCode">
			<result type="stream">
				<param name="contentType">image/jpeg</param>
				<param name="inputName">inputStream</param>
				<param name="bufferSize">1024</param>
			</result>
			<result name="error" type="json">
				<param name="contentType">image/jpeg</param>
				<param name="inputName">inputStream</param>
				<param name="bufferSize">1024</param>
			</result>
		</action>
	</package>
</struts>

 
 フロントページに検証コードが表示されます:login.jsp
 
<div class="code">
	<div>
		<input type="text" name="code" id="codeId" />
	</div>
	<div>
		<a href="javascript:changeImg();">
                <img 	src="code.nl?code=<%=new Date()%>" id="verificationCodeId"	ext:qtip="   "> </a>
	</div>
</div>

 jsコードは次のとおりです.
<script type="text/javascript">
	function changeImg() {
		var img = document.getElementById("verificationCodeId");
		img.src = "code.nl?code=" + Math.random();
	}

	function validateSubmit() {

		var errorMsg = document.getElementById("errorMsgId");
		var userName = document.getElementById("userNameId");
		var password = document.getElementById("passwordId");
		var code = document.getElementById("codeId");
		if (userName.value == null|| userName.value=="") {
			errorMsg.innerHTML = "       ";
			return false;
		}
		if (password.value == null|| password.value=="") {
			errorMsg.innerHTML = "      ";
			return false;
		}

		if (code.value == null|| code.value=="") {
			errorMsg.innerHTML = "       ";
			return false;
		}
		return true;
	}
</script>

ログイン検証のactionで検証コードが正しいかどうかを検証する方法は、次のとおりです.
Object sessionCode = request.getSession().getAttribute("userLoginCode");
	if (sessionCode == null
		|| !user.getRandom().equalsIgnoreCase(sessionCode.toString())) {
		addActionError("     ");
		return;
		}

 
フロントからエラーメッセージを出力する方法は、次のとおりです.
<div class="error">
    <span id="errorMsgId">${action.actionErrors}</span>
</div>