2016年11月9日 星期三

ASP .NET MVC 登入驗證 FormsAuthentication


[AllowAnonymous] //此Class不驗證
public class AccountController : BaseController
{
    [HttpPost]
    public ActionResult LoginGo(Login form)
    {
        Session.RemoveAll();
        Session["LoginInfo"] = null;
        LoginData loginData = new LoginData();
        try
        {
            if (ValidateLogin(form))
            {
                //驗證成功(失敗則重新登入)
                loginData.loginStatus = "00";
                loginData.userId = form.userId;
                loginData.userName = "使用者名稱";

                //表單驗證開始
                FormsAuthenticationTicket authTicket = LoginProcess(form.userId);
                //加密Ticket
                string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
                //建立Cookie
                HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                //將建立的Cookie寫入Cookie
                Response.Cookies.Add(authCookie);

                return RedirectToAction("Login", "Account");
            }

            else
            {
                return RedirectToAction("Login", "Account");
            }
        }
        catch (Exception ex)
        {
            return RedirectToAction("Login", "Account");
        }
    }

    private bool ValidateLogin(Login form)
    {
        //DB驗證,AD驗證寫在此 
        return true;
    }
    
    //將登入資訊寫入Ticket
    private FormsAuthenticationTicket LoginProcess(string userId)
    {
        string roles = "test";
        FormsAuthenticationTicket authTicket = 
            new FormsAuthenticationTicket(
                    1,
                    userId,
                    DateTime.Now,
                    DateTime.Now.AddMinutes(20),
                    false,
                    roles//寫入角色之後角色權限使用
                );
        return authTicket;
    }
}
所有的Controller都繼承BaseController,驗證寫在BaseController[Authorize],若Method或Class不需要驗證則加上[AllowAnonymous]
[Authorize]
public class BaseController : Controller
{
    protected static NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
}
Web.config 配置

2016年3月8日 星期二

JAVA junit測試 AD帳密驗證 + search AD displayName(顯示名稱)

package junit.test.AD;

import java.util.Hashtable;

import javax.naming.AuthenticationException;
import javax.naming.CommunicationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;

import org.junit.Test;


public class AdTest {
 @Test
 public void test() {
//  ResourceBundle res = ResourceBundle.getBundle("config");
//  String ldapURL = res.getString("Active.directory.ldapURL");
  String ldapURL = "ldap://172.23.101.108:389" ;
  System.out.println(ldapURL);
  String account = "admin";
  String password = "p@ssw0rd";
  try{
     LDAP_AUTH_AD(ldapURL, account, password);
   System.out.println("認證成功!");
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }
 }
 public static void LDAP_AUTH_AD(String ldap_url, String account, String password) throws Exception {
     if (account.isEmpty() || password.isEmpty()) throw new Exception("認證失敗!");
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, ldap_url);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, account+"@mizuho.com");
        env.put(Context.SECURITY_CREDENTIALS, password);

        LdapContext ctx = null;
        try {
            ctx = new InitialLdapContext(env, null);
        } catch (AuthenticationException e) {
         /**
         * error Code 說明 : 
         * 525 : 用戶沒有找到
         * 52e : 證號不正確
         * 530 : 此時間不允許登入(not permitted to logon at this time)
         * 532 : 密碼期滿
         * 533 : 帳號不可用
         * 701 : 帳戶期滿
         * 773 : 用戶必須重設密碼
         * data 後面為錯誤代碼
         */
         throw new Exception(e.getMessage() + "認證失敗!");
        } catch (CommunicationException e) {
         throw new Exception("找不到伺服器!");
        } catch (Exception e) {
         throw new Exception("發生未知的錯誤!");
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (NamingException e) {
                }
            }
        }      
    }
 @Test
 public void testQueryAdUser() throws NamingException {
  String userId = "admin" ;
  String ldapURL = "ldap://172.23.101.108:389" ;
  String domainName = "mizuho.com";
  String account = "admin";
  String password = "p@ssw0rd";
  
  Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, ldapURL);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, account+"@"+domainName);
        env.put(Context.SECURITY_CREDENTIALS, password);
        
        LdapContext ldapContext = new InitialLdapContext(env, null);
  
  SearchControls searchCtls = new SearchControls();
  String returnedAtts[] = { "sn", "givenName", "samAccountName","displayName" };
  
  searchCtls.setReturningAttributes(returnedAtts);
  searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
  String searchFilter = "(&(userPrincipalName="+userId+"@"+domainName+"))";
  String searchBase = "dc=mizuho,dc=com";
  
  // initialize counter to total the results
  int totalResults = 0;

  // Search for objects using the filter
  NamingEnumeration answer = ldapContext.search(searchBase,
    searchFilter, searchCtls);

  // Loop through the search results
  while (answer.hasMoreElements()) {
   SearchResult sr = (SearchResult) answer.next();

   totalResults++;

   System.out.println(">>>" + sr.getName());
   String displayName = sr.getName().replace("CN=", "");
   displayName = displayName.split(",")[0] ;
   System.out.println("displayName >>" + displayName);
   Attributes attrs = sr.getAttributes();
   System.out.println(">>>>>>" + attrs.get("samAccountName"));
  }
  System.out.println("Total results: " + totalResults);
  ldapContext.close();
 }
}

JQuery-MenuTree勾選

<table>
  <caption>角色 - 新增</caption>
  <tr>
    <td>
      <fieldset>
        <br />角色名稱: <input type="text" value="" name="roleName"
          id="roleName" maxlength="50" /> <br />
        <legend>權限設定</legend>
        <div id="divTree">

          <ul>
            <li class="folder"><input type="checkbox" status="all"
              class="parent_B30000" id="B30000" name="access" value="B30000">分行管理
              <ul>

                <li><input type="checkbox" class="son_B30000" id="B31000"
                  name="access" value="B31000">強制開關機設定</li>

                <li><input type="checkbox" class="son_B30000" id="B32000"
                  name="access" value="B32000">定期開關機設定</li>

                <li><input type="checkbox" class="son_B30000" id="B33000"
                  name="access" value="B33000">預約開關機設定</li>

              </ul></li>
          </ul>

          <ul>
            <li class="folder"><input type="checkbox" status="all"
              class="parent_B50000" id="B50000" name="access" value="B50000">行員帳號權限管理
              <ul>

                <li><input type="checkbox" class="son_B50000" id="B51000"
                  name="access" value="B51000">帳號管理</li>

                <li><input type="checkbox" class="son_B50000" id="B52000"
                  name="access" value="B52000">角色維護</li>

              </ul></li>
          </ul>

        </div>
      </fieldset>
    </td>
  </tr>
  <tr>
    <td>
      <button type="reset" id="btnReset">重設</button>
      <button type="button" id="btnSubmit">新增</button>
    </td>
  </tr>
</table>
<script>

$( document ).ready(function() {
  $('#btnSubmit').click(function(){
    if($('#roleName').val()==""){
      alert("請輸入角色名稱!");
      return false ;
    }
    var chk = false ;
    $('input[type=checkbox]').each(function () {
        if($(this).prop("checked")){
      chk = true ;
      }
    })
    if(!chk){
      alert("請選擇權限!");
      return false ;
    }else{
      $('#myForm').submit();
    }
  })
  
  $('input[type=checkbox]').click(function(){
    var checkClass = $(this).attr("class");
    console.info(checkClass);
    var parentClass = checkClass.replace("son","parent");
    var tmp = 'input[type=checkbox].'+checkClass ;
    allChk = false ;
    $(tmp).each(function () {
      if($(this).prop("checked")){
        allChk = true ;
      }
      if (allChk){
        var tmp2 = 'input[type=checkbox].'+parentClass
        $(tmp2).prop("checked",true);
      }
      else{
        var tmp2 = 'input[type=checkbox].'+parentClass
        $(tmp2).prop("checked",false);
      }
    })
  })
  
  
  var parentItem = $('input[status="all"]');
  $(parentItem).click(function(){
    if ($(this).prop("checked")){
      var checkClass = $(this).attr("class");
      var sonClass = checkClass.replace("parent","son");
      var tmpSon = 'input[type=checkbox].'+sonClass  ;
      $(tmpSon).prop("checked",true);
    }else{
      var checkClass = $(this).attr("class");
      var sonClass = checkClass.replace("parent","son");
      var tmpSon = 'input[type=checkbox].'+sonClass  ;
      $(tmpSon).prop("checked",false);
    }
  })
})
</script>