簡體   English   中英

Spring security請記住我和自定義身份驗證提供程序

[英]Spring security Remember me and Custom Authentication provider

春天的問題記得我

在我的春季安全應用程序中我有自定義身份驗證提供程序,驗證並返回自定義身份驗證對象和身份驗證工作完美但我有問題春天記住我服務它不能正常工作

但是當我通過正常的Spring安全性進行身份驗證時,通過使用UserDetailService然后記住我的工作完美我的代碼如下所示

package com.websopti.wotms.auth;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import com.websopti.wotms.entity.User;
import com.websopti.wotms.enums.ErrorKey;
import com.websopti.wotms.service.UserService;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    public UserService userService;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String email = authentication.getPrincipal().toString();
        String password = authentication.getCredentials().toString();

        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();

        String username = null;

        try {
            username = userService.authenticate(email, password);
        } catch (IOException e) {
            e.printStackTrace();
        }

        if(username != null && !username.equals("0")){

            User user = userService.findByEmail(email);

            if (user != null) {

                authorities.add(new SimpleGrantedAuthority(user.getRole().name()));
                return (new UsernamePasswordAuthenticationToken(user, null, authorities));

            } else {

                User newUser = new User();
                newUser.setName(username);
                newUser.setEmail(email);
                newUser.setPassword(password);

                userService.register(newUser);

                newUser = userService.findById(newUser.getId());                
                authorities.add(new SimpleGrantedAuthority(newUser.getRole().name()));

                return (new UsernamePasswordAuthenticationToken(newUser, null, authorities));
            }

        } else {

            throw new UsernameNotFoundException(ErrorKey.USER_NOT_FOUND.name());

        }


    }

    @Override
    public boolean supports(Class<?> authentication) {

        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

如果我使用以下代碼進行身份驗證,那么它可以正常工作

package com.websopti.wotms.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.websopti.wotms.entity.User;
import com.websopti.wotms.enums.ErrorKey;
import com.websopti.wotms.service.UserService;

@Service
public class AuthenticationService implements UserDetailsService {

    @Autowired
    public UserService userService;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {

        User user = userService.findByEmail(email);

        if(user != null)
            return user;
        else
            throw new UsernameNotFoundException(ErrorKey.USER_NOT_FOUND.name());
    }

}

有人可以指導我在我的代碼中的問題是什么?

根據文件

請注意,這兩個實現都需要UserDetailsS​​ervice。 如果您使用的身份驗證提供程序不使用UserDetailsS​​ervice(例如,LDAP提供程序),那么除非您的應用程序上下文中還有UserDetailsS​​ervice bean,否則它將無效。

示例默認值remember-me使用TokenBasedRememberMeServices processAutoLoginCookie()方法從cookie中檢索userDetails以驗證用戶/密碼詳細信息。 所以你需要一個自定義userDetailsS​​ervice檢查這個這個

更新:

基本上記住我的功能做了兩件事

  1. 成功登錄后,它會創建一個“記住我”瀏覽器cookie,其中包含基於用戶名,密碼的令牌(如果需要,可以計算並保存在令牌中的令牌,或者可以使用用戶的密碼計算哈希值)。
  2. 當用戶嘗試在沒有任何會話(會話因超時而過期)的情況下訪問受保護的頁面時,則RememberMe服務將嘗試通過從cookie檢索用戶詳細信息來自動登錄用戶,並且可以根據需要驗證用戶詳細信息。

如果您沒有返回UserDetails信息的UserDetailsS​​ervice,那么您需要實現RememberMeServices,如TokenBasedRememberMeServices並調整代碼。

我有同樣的問題,並添加auth.userDetailsService(userService); 修理它

  @Autowired
  private AuthenticationService userDetailsService;
  @Autowired
  private CustomAuthenticationProvider provider;
  @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        //將驗證過程交給自定義驗證工具
        auth.userDetailsService(userService);
        auth.authenticationProvider(provider);
    }

當您使用Spring自定義身份驗證提供程序時,您需要自己記住我的服務並將其配置為spring security配置文件。

以下是供參考的鏈接: https//samerabdelkafi.wordpress.com/2016/01/25/secure-angularjs-application-with-spring-security/

記住我和自定義身份驗證提供程序的問題是:

  1. 您已在自定義身份驗證提供程序中進
  2. 在那之后記得我再次在spring安全鏈中過濾調用userdetails服務。 那時userdetail服務將身份驗證主體作為輸入參數,您無法從dbo獲取任何用戶詳細信息,並且它不會執行此過濾器。

public UserDetails loadUserByUsername(String mobile)throws UsernameNotFoundException {System.out.println(mobile); //如果您已經過身份驗證,那么您可以獲取經過身份驗證的主體用戶對象,並且您將無法獲得任何用戶deatils。 }

我不確定下面的解決方案是否對,但它對我來說很好。

 public Authentication authenticate(Authentication auth) throws AuthenticationException { Customer user = null; user = customerDataManager.findCustomerByMobile(auth.getName()); if ((user == null)) { throw new BadCredentialsException("Invalid username or password"); } final Authentication result = super.authenticate(auth); return result; } 

而不是返回UsernamePasswordAuthenticationToken對象返回認證對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM