springmvc+shiro+maven登録認証と権限付与管理を実現します。


Shiroは、Apacheの次のオープンソースプロジェクトであり、アイデンティティの検証とライセンスを簡素化することを目的としています。
 1:shiroの配置は、mavenを通じてshiro関連jarカバンに加入します。

<!-- shiro --> 
 <dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-core</artifactId> 
  <version>1.2.1</version> 
 </dependency> 
 <dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-web</artifactId> 
  <version>1.2.1</version> 
 </dependency> 
 <dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-ehcache</artifactId> 
  <version>1.2.1</version> 
 </dependency> 
 <dependency> 
  <groupId>org.apache.shiro</groupId> 
  <artifactId>shiro-spring</artifactId> 
  <version>1.2.1</version> 
 </dependency> 
2:Shroフィルタをweb.xmlに追加します。

<!--   shiro       --> 
 <filter> 
  <filter-name>shiroFilter</filter-name> 
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
 </filter> 
 <filter-mapping> 
  <filter-name>shiroFilter</filter-name> 
  <url-pattern>/admin/*</url-pattern> 
 </filter-mapping> 
3:springmvcにshiro配置

<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" 
 xmlns:context="http://www.springframework.org/schema/context" 
 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans  
  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
  http://www.springframework.org/schema/mvc  
  http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd  
  http://www.springframework.org/schema/context  
  http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  http://www.springframework.org/schema/aop  
  http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
  http://www.springframework.org/schema/tx  
  http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "> 
 <!-- web.xml shiro filter   bean --> 
 <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> 
  <!--    ,     --> 
  <property name="securityManager" ref="securityManager" /> 
  <!--    ,      ,         --> 
  <property name="loginUrl" value="/admin/login.do" /> 
  <!--          /admin/index.do,     ,shiro               --> 
  <property name="successUrl" value="/admin/index.do" /> 
  <!--   unauthorizedUrl              --> 
  <property name="unauthorizedUrl" value="/refuse.jsp" /> 
  <!--    filter,               --> 
  <property name="filters"> 
   <map> 
    <!--       FormAuthenticationFilter  shiroFilter  --> 
    <entry key="authc" value-ref="formAuthenticationFilter" /> 
   </map> 
  </property> 
  <property name="filterChainDefinitions"> 
   <value> 
    <!--             --> 
    /images/** = anon 
    /js/** = anon 
    /styles/** = anon 
    <!--    ,      --> 
    /validatecode.jsp = anon 
    <!--    logout.do  ,shiro   session --> 
    /admin/logout.do = logout 
    <!--             ,  url    ,         --> 
    <!-- /items/queryItems.action = perms[item:query] /items/editItems.action  
     = perms[item:edit] --> 
    <!--                   --> 
    /welcome.jsp = user 
    /admin/index.do = user 
    <!-- /** = authc   url             --> 
    /** = authc 
   </value> 
  </property> 
 </bean> 
 <!-- securityManager      --> 
 <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> 
  <property name="realm" ref="customRealm" /> 
  <!--         --> 
  <property name="cacheManager" ref="cacheManager" /> 
  <!--   session    --> 
  <!-- <property name="sessionManager" ref="sessionManager" /> --> 
  <!--     --> 
  <property name="rememberMeManager" ref="rememberMeManager" /> 
 </bean> 
 <!--    realm --> 
 <bean id="customRealm" class="com.zhijianj.stucheck.shiro.CustomRealm"> 
  <!--          realm ,realm               --> 
  <!-- <property name="credentialsMatcher" ref="credentialsMatcher" /> --> 
 </bean> 
 <!--       --> 
 <bean id="credentialsMatcher" 
  class="org.apache.shiro.authc.credential.HashedCredentialsMatcher"> 
  <!--   MD5     --> 
  <property name="hashAlgorithmName" value="md5" /> 
  <!--        --> 
  <property name="hashIterations" value="1" /> 
 </bean> 
 <!--    form      --> 
 <!--   Form          ,            ,        、   loginurl      ,     --> 
 <!--       ,      --> 
 <bean id="formAuthenticationFilter" 
  class="com.zhijianj.stucheck.shiro.CustomFormAuthenticationFilter "> 
  <!--       input  ,   username --> 
  <property name="usernameParam" value="username" /> 
  <!--       input  ,   password --> 
  <property name="passwordParam" value="password" /> 
  <!--    input   ,   rememberMe --> 
  <property name="rememberMeParam" value="rememberMe" /> 
 </bean> 
 <!--       --> 
 <bean id="sessionManager" 
  class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager"> 
  <!-- session     ,     --> 
  <property name="globalSessionTimeout" value="600000" /> 
  <!--      session --> 
  <property name="deleteInvalidSessions" value="true" /> 
 </bean> 
 <!--       --> 
 <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> 
  <property name="cacheManagerConfigFile" value="classpath:shiro-ehcache.xml" /> 
 </bean> 
 <!-- rememberMeManager   , cookie,  cookie       --> 
 <bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager"> 
  <property name="cookie" ref="rememberMeCookie" /> 
 </bean> 
 <!--    cookie --> 
 <bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie"> 
  <!-- rememberMe cookie    --> 
  <constructor-arg value="rememberMe" /> 
  <!--    cookie    30  --> 
  <property name="maxAge" value="2592000" /> 
 </bean> 
</beans> 
4:カスタムRealmコード

public class CustomRealm extends AuthorizingRealm { 
 //   realm    
 @Override 
 public void setName(String name) { 
  super.setName("customRealm"); 
 } 
 @Autowired 
 private AdminUserService adminUserService; 
 /** 
  *    
  */ 
 @Override 
 protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 
  // token               
  //     token       
  String userName = (String) token.getPrincipal(); 
  //    :       userCode       
  TAdminUser adminUser = adminUserService.getAdminUserByUserName(userName); 
  //         null 
  if (adminUser == null) {// 
   return null; 
  } 
  //           
  String password = adminUser.getPassword(); 
  /** 
   *      ,      
   */ 
  AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(adminUser, password, this.getName()); 
    //MD5   +  +     
//<span style="color:#ff0000;">SimpleAuthenticationInfo authcInfo = new SimpleAuthenticationInfo(adminUser, password,ByteSource.Util.bytes(salt), this.getName());</span> 
  return authcInfo; 
 } 
 /** 
  *   ,      <span style="font-family: Arial, Helvetica, sans-serif;">doGetAuthenticationInfo          。</span> 
  */ 
 @Override 
 protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 
  //   principals        
  //  getPrimaryPrincipal             (    doGetAuthenticationInfo       SimpleAuthenticationInfo     ), 
  TAdminUser activeUser = (TAdminUser) principals.getPrimaryPrincipal(); 
  //              
  //             
  TAdminRole adminRoles = adminUserService.getAdminRoles(activeUser); 
  //           
  List<String> permissions = new ArrayList<String>(); 
  if (adminRoles != null) { 
   permissions.add(adminRoles.getRoleKey()); 
  } 
  //       ,      (       permissions) 
  SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo(); 
  //              simpleAuthorizationInfo    
  simpleAuthorizationInfo.addStringPermissions(permissions); 
  return simpleAuthorizationInfo; 
 } 
 //      
 public void clearCached() { 
  PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals(); 
  super.clearCache(principals); 
 } 
} 
5キャッシュの設定
ehcache.xmlコードは以下の通りです。

<ehcache updateCheck="false" name="shiroCache"> 
 <defaultCache 
   maxElementsInMemory="10000" 
   eternal="false" 
   timeToIdleSeconds="120" 
   timeToLiveSeconds="120" 
   overflowToDisk="false" 
   diskPersistent="false" 
   diskExpiryThreadIntervalSeconds="120" 
   /> 
</ehcache> 
ehacheを使用することによって、権限付与の要求は初めてサーバに送信されることは避けられます。
6.カスタムフォームコードフィルタ
Custoom FormAuthentication Filterコードは、認証前に呼び出し、コード検証に使用できます。

public class CustomFormAuthenticationFilter extends FormAuthenticationFilter { 
 //  FormAuthenticationFilter      
 @Override 
 protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { 
  //             
 
  //  session        
  HttpServletRequest httpServletRequest = (HttpServletRequest) request; 
  HttpSession session = httpServletRequest.getSession(); 
  //   session    (      ) 
  String validateCode = (String) session.getAttribute("validateCode");  
  //          
  //       session         
  String randomcode = httpServletRequest.getParameter("randomcode"); 
  if (randomcode != null && validateCode != null && !randomcode.equals(validateCode)) { 
   //       ,          ,  shiroLoginFailure   request  
   httpServletRequest.setAttribute("shiroLoginFailure", "randomCodeError"); 
   //     ,          
   return true; 
  } 
  return super.onAccessDenied(request, response); 
 } 
} 
コードjspインタフェースのコードを確認します。  validatecode.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" 
 pageEncoding="UTF-8"%> 
<%@ page import="java.util.Random"%> 
<%@ page import="java.io.OutputStream"%> 
<%@ page import="java.awt.Color"%> 
<%@ page import="java.awt.Font"%> 
<%@ page import="java.awt.Graphics"%> 
<%@ page import="java.awt.image.BufferedImage"%> 
<%@ page import="javax.imageio.ImageIO"%> 
<% 
 int width = 60; 
 int height = 32; 
 //create the image 
 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
 Graphics g = image.getGraphics(); 
 // set the background color 
 g.setColor(new Color(0xDCDCDC)); 
 g.fillRect(0, 0, width, height); 
 // draw the border 
 g.setColor(Color.black); 
 g.drawRect(0, 0, width - 1, height - 1); 
 // create a random instance to generate the codes 
 Random rdm = new Random(); 
 String hash1 = Integer.toHexString(rdm.nextInt()); 
 // make some confusion 
 for (int i = 0; i < 50; i++) { 
  int x = rdm.nextInt(width); 
  int y = rdm.nextInt(height); 
  g.drawOval(x, y, 0, 0); 
 } 
 // generate a random code 
 String capstr = hash1.substring(0, 4); 
 //         session 
 session.setAttribute("validateCode", capstr); 
 g.setColor(new Color(0, 100, 0)); 
 g.setFont(new Font("Candara", Font.BOLD, 24)); 
 g.drawString(capstr, 8, 24); 
 g.dispose(); 
 //     
 response.setContentType("image/jpeg"); 
 out.clear(); 
 out = pageContext.pushBody(); 
 OutputStream strm = response.getOutputStream(); 
 ImageIO.write(image, "jpeg", strm); 
 strm.close(); 
%> 
7.コントローラの登録方法

/** 
 *       
 * 
 * @return 
 * @throws Exception 
 */ 
@RequestMapping("login.do") 
public String adminPage(HttpServletRequest request) throws Exception { 
 //        request         ,shiroLoginFailure  shiro         
 String exceptionClassName = (String) request.getAttribute("shiroLoginFailure"); 
 //   shiro          ,         
 if (exceptionClassName != null) { 
  if (UnknownAccountException.class.getName().equals(exceptionClassName)) { 
   //            
   throw new CustomJsonException("     "); 
  } else if (IncorrectCredentialsException.class.getName().equals(exceptionClassName)) { 
   throw new CustomJsonException("   /    "); 
  } else if ("randomCodeError".equals(exceptionClassName)) { 
   throw new CustomJsonException("      "); 
  } else { 
   throw new Exception();//                
  } 
 } 
 //           (    ),shiro                  
 //       login   
 return "admin/login"; 
} 
8.ユーザーフィードバックController
ユーザ登録認証に成功した後、CustoomRealmは、doGet Authentication Infoを呼び出した時に、

AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(adminUser, password, this.getName()); 
 return authcInfo; 
Simple AuthenticationInfo構造パラメータの最初のパラメータは、1つのユーザのオブジェクトに導入され、その後、Subject subject=SecurityUtils.get Subject()を介して、のsubject.get Principalはこのオブジェクトを取得します。だから、ユーザー情報を再表示する必要がある時、私はこう呼びます。

@RequestMapping("index.do") 
public String index(Model model) { 
 // shiro session  activeUser 
 Subject subject = SecurityUtils.getSubject(); 
 //      
 TAdminUser adminUser = (TAdminUser) subject.getPrincipal(); 
 //  model     
 model.addAttribute("adminUser", adminUser); 
 return "admin/index"; 
} 
9.jspページでのコントロール権限
まずshiroのヘッダファイルを導入します。

<!-- shiro    --> 
<%@ taglib uri="http://shiro.apache.org/tags" prefix="shiro"%> 
shiroラベルで権限を処理する

<!--  curd         ,         ,    if(hasPermission(curd)) --> 
    <shiro:hasPermission name="curd"> 
     <BR /> 
                   
    </shiro:hasPermission> 
10.制御権限
@RequiresPermissionsの注釈により、このcontrollerの中のある要求方法を実行するために必要な権限を指定します。

@RequestMapping("/queryInfo.do") 
 @RequiresPermissions("q")//    "q"   
 public ModelAndView queryItems(HttpServletRequest request) throws Exception { } 
11 MD 5暗号化塩処理
ここではパスワードの変更を例にとって、新しいパスワード(平文)を取得した後、MD 5による暗号化+塩+3回暗号化を例にとります。

@RequestMapping("updatePassword.do") 
 @ResponseBody 
 public String updateAdminUserPassword(String newPassword) { 
  //  shiro session  activeUser 
  Subject subject = SecurityUtils.getSubject(); 
  //       
  TAdminUser adminUser = (TAdminUser) subject.getPrincipal(); 
  //   salt,     
  SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator(); 
  String salt = secureRandomNumberGenerator.nextBytes().toHex(); 
  Md5Hash md5 = new Md5Hash(newPassword, salt, 3); 
  String newMd5Password = md5.toHex(); 
  //       
  adminUser.setPassword(newMd5Password); 
  //     
  adminUser.setSalt(salt); 
  adminUserService.updateAdminUserPassword(adminUser); 
  return newPassword; 
 } 
締め括りをつける
以上述べたのは小编でご绍介したspringmvc+shiro+mavenが登录の认证と権限の授権管理を実现しました。皆さんに助けてほしいです。ここでも私たちのサイトを応援してくれてありがとうございます。