2016-08-16 2 views
1

Ich benutze Apache Shiro Plugin in Grails für den Umgang mit Benutzer Authentifizierung.Login mit passwordHash in Apache Shiro Grails

Ich möchte eine Funktion zum Admin-Teil des Systems hinzufügen, wo unser Administrator für einen bestimmten Benutzer anmelden könnte.

Ich möchte vermeiden, eine neue komplexe Schnittstelle für Admin erstellen.

Wie melde ich mich als Benutzer an, wenn ich sein Passwort nicht kenne, aber nur sein Passwort Hash?

Antwort

0

Ich löste es schließlich, aber ich bin mir nicht sicher über die Sicherheit meiner Lösung, so möchte ich Sie darauf einen Kommentar abgeben.

Ich habe neue Aktion SignIn erstellt, die in Admin-Controller ist. Dieser Controller ist nur für den Administrator und sonst niemand zugänglich. Die Aktion sieht so aus:

def signIn(String username) { 

     def authToken = new UsernamePasswordToken(username, params.password as String) 

     // Specific setting for administrator signIn 
     // 
     params.rememberMe = false 
     params.targetUri = '/' 
     authToken.host = 'admin' 

     // If a controller redirected to this page, redirect back 
     // to it. Otherwise redirect to the root URI. 
     def targetUri = params.targetUri ?: "/index/index" 

     // Handle requests saved by Shiro filters. 
     SavedRequest savedRequest = WebUtils.getSavedRequest(request) 
     if (savedRequest) { 
      targetUri = savedRequest.requestURI - request.contextPath 
      if (savedRequest.queryString) targetUri = targetUri + '?' + savedRequest.queryString 
     } 

     try{ 
      // Perform the actual login. An AuthenticationException 
      // will be thrown if the username is unrecognised or the 
      // password is incorrect. 
      SecurityUtils.subject 
      SecurityUtils.subject.login(authToken) 

      log.info "Redirecting to ${targetUri}." 
      redirect(uri: targetUri) 
     } 
     catch (AuthenticationException ex){ 
      // Authentication failed, so display the appropriate message 
      // on the login page. 
      log.info "Authentication failure for user ${params.username}." 
      flash.message = message(code: "login.failed") 

      // Keep the username and "remember me" setting so that the 
      // user doesn't have to enter them again. 
      def m = [ username: params.username ] 

      // Remember the target URI too. 
      if (params.targetUri) { 
       m["targetUri"] = params.targetUri 
      } 

      // Now redirect back to the login page. 
      redirect(action: "login", params: m) 
     } 
    } 

Und ich habe auch meine DbShiroRealm leicht modifiziert.

def authenticate(authToken) { 


    log.info "Attempting to authenticate ${authToken.username} in DB realm..." 
    def username = authToken.username 

    // Null username is invalid 
    if (username == null) { 
     throw new AccountException("Null usernames are not allowed by this realm.") 
    } 

    // Get the user with the given username. If the user is not 
    // found, then they don't have an account and we throw an 
    // exception. 
    def user = User.findByUsername(username) 
    if (!user) { 
     throw new UnknownAccountException("No account found for user [${username}]") 
    } 

    log.info "Found user ${user.username} in DB" 

    // Now check the user's password against the hashed value stored 
    // in the database. 
    def account = new SimpleAccount(username, user.password, "ShiroDbRealm") 

    if(!(authToken.host == 'admin')) { // skips password authentication 
     if (!credentialMatcher.doCredentialsMatch(authToken, account)) { 
      log.info "Invalid password (DB realm)" 
      throw new IncorrectCredentialsException("Invalid password for user ${username}") 
     } 
    } 

    return account 
} 

Ich verwenden Host-Feld in UsernamePasswordToken Informationen zu tragen, die in.

Es loggt wäre angemessen UsernamePasswordToken außer Kraft zu setzen und zusätzliches boolean Feld hinzufügen für das Überspringen Passwort-Authentifizierung.

Verwandte Themen