Методы аутентификации с использованием логина, пароля и токена доступа к Facebook с использованием Spring Security (не OJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Методы аутентификации с использованием логина, пароля и токена доступа к Facebook с использованием Spring Security (не O

Сообщение Anonymous »

Я уже реализовал регистрацию и аутентификацию с использованием логина и пароля с помощью Spring Security. Я сделал это, используя этот урок. Но теперь я хочу обеспечить регистрацию и аутентификацию с помощью Facebook Id. Я получу токен доступа пользователя Facebook в мобильном приложении, затем отправлю этот токен доступа на свой сервер Spring (поэтому OAuth не подходит), проверю его с помощью API Facebook и получу идентификатор пользователя Facebook.
Обратите внимание, что в моей базе данных уже есть таблица Users со столбцами user_id, login, пароля, fb_id, поэтому есть два варианта регистрации: либо у пользователя будет логин и пароль, либо у пользователя у меня будет только учетная запись Facebook, и я буду использовать его идентификатор Facebook.

Наконец, мне просто нужно аутентифицировать этого пользователя и вернуть ему токен JWT.

Уже существующий код.

SecurityConfig:

Код: Выделить всё

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
securedEnabled = true,
jsr250Enabled = true,
prePostEnabled = true
)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CustomUserDetailsService customUserDetailsService;

@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;

@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}

@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder
.userDetailsService(customUserDetailsService)
.passwordEncoder(passwordEncoder());
}

@Bean(BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
.csrf()
.disable()
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/",
"/favicon.ico",
"/**/*.png",
"/**/*.gif",
"/**/*.svg",
"/**/*.jpg",
"/**/*.html",
"/**/*.css",
"/**/*.js")
.permitAll()
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/api/user/checkUsernameAvailability", "/api/user/checkEmailAvailability")
.permitAll()
.antMatchers(HttpMethod.GET, "/api/polls/**", "/api/users/**")
.permitAll()
.anyRequest()
.authenticated();

// Add our custom JWT security filter
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);

}
}
Текущий пользователь:

Код: Выделить всё

@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@AuthenticationPrincipal
public @interface CurrentUser {

}
CustomUserDetailsService:

Код: Выделить всё

@Service
public class CustomUserDetailsService implements UserDetailsService {

@Autowired
UserRepository userRepository;

@Override
@Transactional
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException {
// Let people login with either username or email
User user = userRepository.findByPhone(username)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with username or email : " + username)
);

return user;
}

// This method is used by JWTAuthenticationFilter
@Transactional
public UserDetails loadUserById(Long id) {
User user = userRepository.findById(id).orElseThrow(
() ->  new UsernameNotFoundException("User not found with id : " + id)
);

return user;
}
}
JwtAuthenticationEntryPoint:

Код: Выделить всё

@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {

private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException, ServletException {
logger.error("Responding with unauthorized error.  Message - {}", e.getMessage());
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
"Sorry, You're not authorized to access this resource.");
}
}
JwtAuthenticationFilter:

Код: Выделить всё

public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Autowired
private JwtTokenProvider tokenProvider;

@Autowired
private CustomUserDetailsService customUserDetailsService;

private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationFilter.class);

@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
try {
String jwt = getJwtFromRequest(request);

if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
Long userId = tokenProvider.getUserIdFromJWT(jwt);

UserDetails userDetails = customUserDetailsService.loadUserById(userId);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}

filterChain.doFilter(request, response);
}

private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) &&  bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7, bearerToken.length());
}
return null;
}
}
JwtTokenProvider:

Код: Выделить всё

@Component
public class JwtTokenProvider {

private static final Logger logger = LoggerFactory.getLogger(JwtTokenProvider.class);

@Value("${app.jwtSecret}")
private String jwtSecret;

@Value("${app.jwtExpirationInMs}")
private int jwtExpirationInMs;

public String generateToken(Authentication authentication) {

User user = (User) authentication.getPrincipal();

Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);

return Jwts.builder()
.setSubject(Long.toString(user.getId()))
.setIssuedAt(new Date())
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}

public Long getUserIdFromJWT(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();

return Long.parseLong(claims.getSubject());
}

public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
logger.error("Invalid JWT signature");
} catch (MalformedJwtException ex) {
logger.error("Invalid JWT token");
} catch (ExpiredJwtException ex) {
logger.error("Expired JWT token");
} catch (UnsupportedJwtException ex) {
logger.error("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
logger.error("JWT claims string is empty.");
}
return false;
}
}
Контроллер аутентификации:

Код: Выделить всё

//...
@PostMapping("/authorization")
public AuthorizationResponse AuthauthenticateUser(@Valid @RequestBody LoginRequest loginRequest) {

Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getPhone(),
loginRequest.getPassword()
)
);

SecurityContextHolder.getContext().setAuthentication(authentication);

String jwt = tokenProvider.generateToken(authentication);

User user = (User)authentication.getPrincipal();

AuthorizationResponse authorizationResponse = new AuthorizationResponse(user.getId(), jwt);

return authorizationResponse;
}
//...
Итак, как мне достичь этой цели с помощью Spring Security?

Подробнее здесь: https://stackoverflow.com/questions/522 ... -using-spr
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»