Java, SSM + Shiro system login verification code implementation

 

1, the verification code generated class:

import java.util.Random;
import java.awt.image.BufferedImage;
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
/**
 * Code generator class, may generate a digital, uppercase, lowercase, and mixing the three types of codes. Support for custom code to verify the number of characters; support for custom code size of the picture; support for special characters to be excluded from the definition;
 * Number of custom support line interference; support custom color graphic codes
 */
public class ValidateCode {
 /**
  * Code type only numbers 0-9
  */
 public static final int TYPE_NUM_ONLY = 0;
 /**
  * Code type only letters, uppercase letters, lowercase letters mixed
  */
 public static final int TYPE_LETTER_ONLY = 1;
 /**
  * The type of digital codes, uppercase letters, lowercase letters mixed
  */
 public static final int TYPE_ALL_MIXED = 2;
 /**
  * The type of digital codes, mixed uppercase
  */
 public static final int TYPE_NUM_UPPER = 3;
 /**
  * The type of digital codes, mixed lowercase
  */
 public static final int TYPE_NUM_LOWER = 4;
 /**
  * Code type only uppercase letters
  */
 public static final int TYPE_UPPER_ONLY = 5;
 /**
  * Code type only lowercase
  */
 public static final int TYPE_LOWER_ONLY = 6;
 private ValidateCode() {
 }
 /**
  Generating a verification code string *
  * 
  * @param type
  * Type codes, refer to the static properties of the class
  * @param length
  * Length codes, an integer greater than 0,
  * @param exChars
  * Need to exclude special characters (only numbers, letters, codes efficiently mixed, without exclusion was null)
  * @return 验证码字符串
  */
 public static String generateTextCode(int type, int length, String exChars) {
  if (length <= 0)
   return "";
  StringBuffer code = new StringBuffer();
  int i = 0;
  R & lt the Random = new new the Random ();
   Switch (type) {
   // only digital 
  Case TYPE_NUM_ONLY:
    the while (I < length) {
     int T = r.nextInt (10 );
     IF (exChars == null || exChars.indexOf (T + "") <0) { // exclude special characters 
     code.append (t);
     i++;
    }
   }
   BREAK ;
   // only letters (i.e. uppercase letters, lowercase letters mixed) 
  Case TYPE_LETTER_ONLY:
    the while (I < length) {
     int T = r.nextInt (123 );
     IF ((T> 97 || = (T> = 65 && T <= 90)) && (exChars == null || exChars.indexOf (( char ) T) <0 )) {
     code.append((char) t);
     i++;
    }
   }
   BREAK ;
   // numbers, uppercase letters, lowercase letters mixed 
  Case TYPE_ALL_MIXED:
    the while (I < length) {
     int T = r.nextInt (123 );
     IF ((T> 97 || = (T> T && = 65 <= 90) || (T> T && = 48 <= 57 is ))
       && (exChars == null || exChars.indexOf (( char ) T) <0 )) {
     code.append((char) t);
     i++;
    }
   }
   break;
  // 数字、大写字母混合
  case TYPE_NUM_UPPER:
   while (i < length) {
    int t = r.nextInt(91);
    if ((t >= 65 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
     code.append((char) t);
     i++;
    }
   }
   break;
  // 数字、小写字母混合
  case TYPE_NUM_LOWER:
   while (i < length) {
    int t = r.nextInt(123);
    if ((t >= 97 || (t >= 48 && t <= 57)) && (exChars == null || exChars.indexOf((char) t) < 0)) {
     code.append((char) t);
     i++;
    }
   }
   break;
  // 仅大写字母
  case TYPE_UPPER_ONLY:
   while (i < length) {
    int t = r.nextInt(91);
    if ((t >= 65) && (exChars == null || exChars.indexOf((char) t) < 0)) {
     code.append((char) t);
     i++;
    }
   }
   break;
  // 仅小写字母
  case TYPE_LOWER_ONLY:
   while (i < length) {
    int t = r.nextInt(123);
    if ((t >= 97) && (exChars == null || exChars.indexOf((char) t) < 0)) {
     code.append((char) t);
     i++;
    }
   }
   break;
  }
  return code.toString();
 }
 /**
  * Verification code has been generated CAPTCHA image
  * 
  * @param textCode
  * Text Code
  * @param width
  * Image Width
  * @param height
  * Image Height
  * @param interLine
  * The number of lines of picture interference
  * @param randomLocation
  * The level of the position of each character whether random
  * @param backColor
  * Color pictures, if it is null, then the use of random colors
  * @param foreColor
  * Font color, if it is null, then the use of random colors
  * @param lineColor
  * Line color interference, if it is null, then random color
  * @return 图片缓存对象
  */
 public static BufferedImage generateImageCode(String textCode, int width, int height, int interLine,
   boolean randomLocation, Color backColor, Color foreColor, Color lineColor) {
  BufferedImage bim = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
  Graphics g = bim.getGraphics();
  // 画背景图
  g.setColor(backColor == null ? getRandomColor() : backColor);
  g.fillRect(0, 0, width, height);
  // 画干扰线
  Random r = new Random();
  if (interLine > 0) {
   int x = 0, y = 0, x1 = width, y1 = 0;
   for (int i = 0; i < interLine; i++) {
    g.setColor(lineColor == null ? getRandomColor() : lineColor);
    y = r.nextInt(height);
    y1 = r.nextInt(height);
    g.drawLine(x, y, x1, y1);
   }
  }
  // write code
   // g.setColor (getRandomColor ());
   // g.setColor (isSimpleColor Color.BLACK:? Color.WHITE);
   // font size of the image height% 80 
  int fsize = ( int ) ( 0.8 * height );
   int FX = height - fsize;
   int FY = fsize;
  g.setFont ( new new the Font ( "the Default" , Font.PLAIN, fsize));
   // write the character codes 
  for ( int I = 0; I <textCode.length (); I ++ ) {
   fy = randomLocation (? int ) ((Math.random () * 0.3 + 0.6) * height): fy; // each character level if random 
   g.setColor (foreColor == null ? :; getRandomColor () foreColor)
   g.drawString(textCode.charAt(i) + "", fx, fy);
   fx += fsize * 0.9;
  }
  g.dispose ();
  return bim;
 }
 /**
  * Generate image verification code
  * 
  * @param type
  * Type codes, refer to the static properties of the class
  * @param length
  * Code characters in length, an integer greater than 0,
  * @param exChars
  * Subject to exclude special characters
  * @param width
  * Image Width
  * @param height
  * Image Height
  * @param interLine
  * The number of lines of picture interference
  * @param randomLocation
  * The level of the position of each character whether random
  * @param backColor
  * Color pictures, if it is null, then the use of random colors
  * @param foreColor
  * Font color, if it is null, then the use of random colors
  * @param lineColor
  * Line color interference, if it is null, then random color
  * @return 图片缓存对象
  */
 public static BufferedImage generateImageCode(int type, int length, String exChars, int width, int height,
   int interLine, boolean randomLocation, Color backColor, Color foreColor, Color lineColor) {
  String textCode = generateTextCode(type, length, exChars);
  BufferedImage bim = generateImageCode(textCode, width, height, interLine, randomLocation, backColor, foreColor,
    lineColor);
  return bim;
 }
 /**
  * Generates random colors
  * 
  * @return
  */
 private static Color getRandomColor() {
  Random r = new Random();
  Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
  return c;
 }
}

2、Controller

/**
 Generating codes *
 * @param request
 * @param response
 * @throws IOException
 * @ ValidateCode.generateTextCode (character type codes, length codes, special characters should be excluded)
 * @ ValidateCode.generateImageCode (verification code text, picture width, picture height, the number of lines of interference, whether random height position of the character, image color, font color, line color interference)
 */
@RequestMapping(value = "validateCode")
public void validateCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
 response.setHeader("Cache-Control", "no-cache");
 String verifyCode = ValidateCode.generateTextCode(ValidateCode.TYPE_NUM_LOWER, 4, null);
 request.getSession().setAttribute("validateCode", verifyCode);
 response.setContentType("image/jpeg");
 BufferedImage bim = ValidateCode.generateImageCode(verifyCode, 90, 30, 5, true, Color.WHITE, Color.BLUE, null);
 ImageIO.write(bim, "JPEG", response.getOutputStream());
}
/**
 * Logon request
 * @param 
 */
@RequestMapping(value = "login", method = RequestMethod.POST, produces = "text/html; charset=utf-8")
public String login(HttpServletRequest request, HttpServletResponse response, UserEntity user) {
 //首先进行验证码验证
 Session session = SecurityUtils.getSubject().getSession();
 String code = (String) session.getAttribute("validateCode");
 String submitCode = WebUtils.getCleanParam(request, "validateCode");
 if (StringUtils.isEmpty(submitCode) || !StringUtils.equals(code,submitCode.toLowerCase())) {
  request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100000);
  request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_VALIDATECODE);
  return "login";
 }
 // I want to get SecurityUtils.getSubject () object. . Access address must follow within interception of shiro address. Not a null pointer then will report 
 the Subject Sub = SecurityUtils.getSubject ();
  // user account and password input into the memory ,, .. UsernamePasswordToken object and then compare the internal authentication shiro,
  // authentication executor process referred ShiroDbRealm in doGetAuthenticationInfo
  // performs the above authentication is successful when the downwardly authentication failure will be thrown 
 UsernamePasswordToken token = new new UsernamePasswordToken (user.getAccountName (), user.getPassWord ());
  the try {
  sub.login(token);
 } catch (LockedAccountException lae) {
  token.clear();
  request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100002);
  request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_SYSTEMERROR);
  return "login";
 } catch (ExcessiveAttemptsException e) {
  token.clear();
  request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100003);
  request.setAttribute("LOGIN_ERROR_MESSAGE","账号:" + user.getUserName() + LoginConstant.LOGIN_ERROR_MESSAGE_MAXERROR);
  return "login";
 } catch (AuthenticationException e) {
  token.clear();
  request.setAttribute("LOGIN_ERROR_CODE", LoginConstant.LOGIN_ERROR_CODE_100001);
  request.setAttribute("LOGIN_ERROR_MESSAGE", LoginConstant.LOGIN_ERROR_MESSAGE_USERERROR);
  return "login";
 }
 return "redirect:/index.shtml";
}

note:

Login method which some of the parameters of the definition:

public  interface LoginConstant
{
 String LOGIN_ERROR_CODE_100000 = "100000";
 LOGIN_ERROR_MESSAGE_VALIDATECODE String = "Verification code input errors, please re-enter!" ;
 String LOGIN_ERROR_CODE_100001 = "100001";
 LOGIN_ERROR_MESSAGE_USERERROR String = "error account or password, please try again!" ;
 String LOGIN_ERROR_CODE_100002 = "100002";
 LOGIN_ERROR_MESSAGE_SYSTEMERROR String = "User has been locked can not log in, please contact your administrator!" ;
 String LOGIN_ERROR_CODE_100003 = "100003";
 LOGIN_ERROR_MESSAGE_MAXERROR String = "too many failed login lock 10 minutes!" ;
 String LOGIN_ERROR_CODE_100004 = "100004";
 LOGIN_ERROR_MESSAGE_FORCELOGOUT String = "You have been forced to withdraw from the administrator, please log in again ' ;
}

3, login jsp (important Code)

Path information:

<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%>

js: to replace the verification code picture

<script>
 function reloadValidateCode(){
  $("#validateCodeImg").attr("src","<%=basePath%>/validateCode.shtml?data=" + new Date() + Math.floor(Math.random()*24));
 }
</script>

Login form inside the label:

<img id="validateCodeImg" src="<%=basePath%>/validateCode.shtml" />  <a href="#" rel="external nofollow" onclick="javascript:reloadValidateCode();">看不清?</a>

4, Shiro anonymous access configuration (not configured can not generate a CAPTCHA)

<-! Custom filterChainDefinitionMap ->
 <bean id="chainDefinitionSectionMetaSource" class="com.collection.shiro.ChainDefinitionSectionMetaSource">
  <property name="filterChainDefinitions">
   <value>
    anon = /validateCode.shtml // add this line
   </value>
  </property>
 </bean>

The above is in Java SSM + Shiro small series to introduce the system login authentication implementation code, we want to help, if you have any questions please give me a message, Xiao Bian will promptly reply to everyone. In this I am also very grateful for the support of the home-site scripting!

 

Original Address: https: //www.jb51.net/article/105481.htm

 

Guess you like

Origin www.cnblogs.com/it-deepinmind/p/11782668.html