poprawione logowanie poprzez USOS
This commit is contained in:
parent
a2666f0f05
commit
bd6c1e5006
@ -19,6 +19,13 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
@ -15,6 +15,7 @@ import studycave.studycaverestservice.model.user.User;
|
|||||||
import studycave.studycaverestservice.usos.AuthorizationService;
|
import studycave.studycaverestservice.usos.AuthorizationService;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -43,29 +44,14 @@ public class UsosController {
|
|||||||
String oauth_verifier = request.getHeader("oauth_verifier");
|
String oauth_verifier = request.getHeader("oauth_verifier");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return ResponseEntity.status(HttpStatus.OK).headers(responseHeaders).body(authorizationService.authorize(oauth_token, oauth_token_secret, oauth_verifier));
|
String responseToken = authorizationService.authorize(oauth_token, oauth_token_secret, oauth_verifier);
|
||||||
} catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) {
|
responseHeaders.add("authorization", responseToken);
|
||||||
|
return ResponseEntity.status(HttpStatus.OK).headers(responseHeaders).body(responseToken);
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidKeyException | IOException e) {
|
||||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).headers(responseHeaders).body(e.getCause().toString());
|
return ResponseEntity.status(HttpStatus.BAD_REQUEST).headers(responseHeaders).body(e.getCause().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiImplicitParams({
|
|
||||||
@ApiImplicitParam(name = "oauth_token", value = "User's oauth_token", required = true, dataType = "string", paramType = "header"),
|
|
||||||
@ApiImplicitParam(name = "oauth_token_secret", value = "User's oauth_token_secret", required = true, dataType = "string", paramType = "header")
|
|
||||||
})
|
|
||||||
@GetMapping("/details")
|
|
||||||
public ResponseEntity<Object> userDetails(HttpServletRequest request) {
|
|
||||||
HttpHeaders responseHeaders = new HttpHeaders();
|
|
||||||
String oauth_token = request.getHeader("oauth_token");
|
|
||||||
String oauth_token_secret = request.getHeader("oauth_token_secret");
|
|
||||||
|
|
||||||
try {
|
|
||||||
return ResponseEntity.status(HttpStatus.OK).headers(responseHeaders).body(authorizationService.checkUserDetails(oauth_token, oauth_token_secret));
|
|
||||||
} catch (InvalidKeyException | UnsupportedEncodingException | NoSuchAlgorithmException e) {
|
|
||||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).headers(responseHeaders).body(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/request_token")
|
@GetMapping("/request_token")
|
||||||
public ResponseEntity<String> getToken(@RequestParam(required = false, defaultValue = "oob") String oauth_callback) {
|
public ResponseEntity<String> getToken(@RequestParam(required = false, defaultValue = "oob") String oauth_callback) {
|
||||||
HttpHeaders responseHeaders = new HttpHeaders();
|
HttpHeaders responseHeaders = new HttpHeaders();
|
||||||
|
@ -36,6 +36,9 @@ public class User {
|
|||||||
@Column(unique=true)
|
@Column(unique=true)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
|
@OneToOne(cascade = CascadeType.ALL)
|
||||||
|
private UsosUser usosUser;
|
||||||
|
|
||||||
@OneToMany(mappedBy="user",cascade = CascadeType.ALL)
|
@OneToMany(mappedBy="user",cascade = CascadeType.ALL)
|
||||||
List<StudyGroupMember> groupMembers = new ArrayList<>();
|
List<StudyGroupMember> groupMembers = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import org.springframework.security.core.userdetails.User;
|
|||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
@ -11,9 +12,11 @@ import static java.util.Collections.emptyList;
|
|||||||
@Service
|
@Service
|
||||||
public class UserDetailsServiceImpl implements UserDetailsService {
|
public class UserDetailsServiceImpl implements UserDetailsService {
|
||||||
private UserRepository applicationUserRepository;
|
private UserRepository applicationUserRepository;
|
||||||
|
private BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||||
|
|
||||||
public UserDetailsServiceImpl(UserRepository applicationUserRepository) {
|
public UserDetailsServiceImpl(UserRepository applicationUserRepository, BCryptPasswordEncoder bCryptPasswordEncoder) {
|
||||||
this.applicationUserRepository = applicationUserRepository;
|
this.applicationUserRepository = applicationUserRepository;
|
||||||
|
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -22,6 +25,9 @@ public class UserDetailsServiceImpl implements UserDetailsService {
|
|||||||
if (applicationUser == null) {
|
if (applicationUser == null) {
|
||||||
throw new UsernameNotFoundException(username);
|
throw new UsernameNotFoundException(username);
|
||||||
}
|
}
|
||||||
|
if (applicationUser.getUsosUser() != null)
|
||||||
|
applicationUser.setPassword(applicationUser.getUsosUser().getPassword());
|
||||||
|
|
||||||
return new User(applicationUser.getUsername(), applicationUser.getPassword(), emptyList());
|
return new User(applicationUser.getUsername(), applicationUser.getPassword(), emptyList());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package studycave.studycaverestservice.model.user;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class UsosUser {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name="id")
|
||||||
|
private String usosId;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
@ -45,6 +45,8 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
|
|||||||
studycave.studycaverestservice.model.user.User creds = new ObjectMapper()
|
studycave.studycaverestservice.model.user.User creds = new ObjectMapper()
|
||||||
.readValue(req.getInputStream(), studycave.studycaverestservice.model.user.User.class);
|
.readValue(req.getInputStream(), studycave.studycaverestservice.model.user.User.class);
|
||||||
|
|
||||||
|
// if ()
|
||||||
|
|
||||||
return authenticationManager.authenticate(
|
return authenticationManager.authenticate(
|
||||||
new UsernamePasswordAuthenticationToken(
|
new UsernamePasswordAuthenticationToken(
|
||||||
creds.getUsername(),
|
creds.getUsername(),
|
||||||
|
@ -3,33 +3,53 @@ package studycave.studycaverestservice.usos;
|
|||||||
|
|
||||||
import io.restassured.response.Response;
|
import io.restassured.response.Response;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
|
import org.apache.http.Header;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
import org.apache.http.NameValuePair;
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
import org.apache.http.client.utils.URLEncodedUtils;
|
import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.HttpClientBuilder;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import studycave.studycaverestservice.PropertiesLoader;
|
import studycave.studycaverestservice.PropertiesLoader;
|
||||||
import studycave.studycaverestservice.model.user.User;
|
import studycave.studycaverestservice.model.user.User;
|
||||||
import studycave.studycaverestservice.model.user.UserRepository;
|
import studycave.studycaverestservice.model.user.UserRepository;
|
||||||
import studycave.studycaverestservice.model.user.dto.UserDTO;
|
import studycave.studycaverestservice.model.user.UsosUser;
|
||||||
|
import studycave.studycaverestservice.utils.PasswordGenerator;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import javax.crypto.Mac;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static io.restassured.RestAssured.get;
|
import static io.restassured.RestAssured.get;
|
||||||
import static io.restassured.RestAssured.when;
|
import static io.restassured.RestAssured.when;
|
||||||
|
import static studycave.studycaverestservice.utils.PasswordGenerator.*;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AuthorizationService {
|
public class AuthorizationService {
|
||||||
|
|
||||||
|
private BCryptPasswordEncoder bCryptPasswordEncoder;
|
||||||
|
|
||||||
|
public AuthorizationService(BCryptPasswordEncoder bCryptPasswordEncoder) {
|
||||||
|
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
|
||||||
|
}
|
||||||
|
|
||||||
private static final String ENC = "UTF-8";
|
private static final String ENC = "UTF-8";
|
||||||
private static final String HMAC_SHA1 = "HmacSHA1";
|
private static final String HMAC_SHA1 = "HmacSHA1";
|
||||||
private static Base64 base64 = new Base64();
|
private static Base64 base64 = new Base64();
|
||||||
@ -39,7 +59,7 @@ public class AuthorizationService {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository userRepository;
|
private UserRepository userRepository;
|
||||||
|
|
||||||
public String authorize(String oauth_token, String oauth_token_secret, String oauth_verifier) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
public String authorize(String oauth_token, String oauth_token_secret, String oauth_verifier) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
|
||||||
List<NameValuePair> queryParams = new ArrayList<>();
|
List<NameValuePair> queryParams = new ArrayList<>();
|
||||||
queryParams.add(new BasicNameValuePair("oauth_consumer_key", propertiesLoader.getKey()));
|
queryParams.add(new BasicNameValuePair("oauth_consumer_key", propertiesLoader.getKey()));
|
||||||
queryParams.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
|
queryParams.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
|
||||||
@ -51,8 +71,14 @@ public class AuthorizationService {
|
|||||||
String oauth_signature = getSignature("GET", URLEncoder.encode(propertiesLoader.getUsosApiURL() + "/oauth/access_token", ENC), URLEncoder.encode(URLEncodedUtils.format(queryParams, ENC), ENC), oauth_token_secret);
|
String oauth_signature = getSignature("GET", URLEncoder.encode(propertiesLoader.getUsosApiURL() + "/oauth/access_token", ENC), URLEncoder.encode(URLEncodedUtils.format(queryParams, ENC), ENC), oauth_token_secret);
|
||||||
queryParams.add(new BasicNameValuePair("oauth_signature", oauth_signature));
|
queryParams.add(new BasicNameValuePair("oauth_signature", oauth_signature));
|
||||||
String url = "/oauth/access_token?" + URLEncodedUtils.format(queryParams, ENC);
|
String url = "/oauth/access_token?" + URLEncodedUtils.format(queryParams, ENC);
|
||||||
|
String response = when().get(url).body().asString();
|
||||||
return when().get(url).body().asString();
|
if (response.contains("oauth_token") && response.contains("oauth_token_secret") && response.contains("&")) {
|
||||||
|
String[] tokens = response.split("&");
|
||||||
|
oauth_token = tokens[0].replace("oauth_token=", "");
|
||||||
|
oauth_token_secret = tokens[1].replace("oauth_token_secret=", "");
|
||||||
|
return createUserAccountAndReturnHeaderToken(oauth_token, oauth_token_secret);
|
||||||
|
}
|
||||||
|
return "authorization failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String requestToken(String oauth_callback) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
public String requestToken(String oauth_callback) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
||||||
@ -89,7 +115,7 @@ public class AuthorizationService {
|
|||||||
return loggedOut;
|
return loggedOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User checkUserDetails(String oauth_token, String oauth_token_secret) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
|
private String createUserAccountAndReturnHeaderToken(String oauth_token, String oauth_token_secret) throws IOException, InvalidKeyException, NoSuchAlgorithmException {
|
||||||
List<NameValuePair> queryParams = new ArrayList<>();
|
List<NameValuePair> queryParams = new ArrayList<>();
|
||||||
queryParams.add(new BasicNameValuePair("oauth_consumer_key", propertiesLoader.getKey()));
|
queryParams.add(new BasicNameValuePair("oauth_consumer_key", propertiesLoader.getKey()));
|
||||||
queryParams.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
|
queryParams.add(new BasicNameValuePair("oauth_nonce", "" + (int) (Math.random() * 100000000)));
|
||||||
@ -108,11 +134,25 @@ public class AuthorizationService {
|
|||||||
|
|
||||||
id = responseJSON.getString("id");
|
id = responseJSON.getString("id");
|
||||||
|
|
||||||
//User user = getUserFromDB(id);
|
|
||||||
|
Optional<User> userCheck = userRepository.findByUsername(id);
|
||||||
|
String generatedPassword = PasswordGenerator.generatePassword(16, ALPHA_CAPS + ALPHA + NUMERIC);
|
||||||
|
if (!userCheck.isPresent()) {
|
||||||
User user = new User();
|
User user = new User();
|
||||||
|
UsosUser usosUser = new UsosUser(id, bCryptPasswordEncoder.encode(generatedPassword));
|
||||||
|
user.setUsosUser(usosUser);
|
||||||
user.setName(responseJSON.getString("first_name"));
|
user.setName(responseJSON.getString("first_name"));
|
||||||
user.setSurname(responseJSON.getString("last_name"));
|
user.setSurname(responseJSON.getString("last_name"));
|
||||||
return userRepository.save(user);
|
user.setUsername(id);
|
||||||
|
user = userRepository.save(user);
|
||||||
|
return getAuthToken(user.getUsername(), generatedPassword);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
User user = userCheck.get();
|
||||||
|
user.getUsosUser().setPassword(bCryptPasswordEncoder.encode(generatedPassword));
|
||||||
|
user = userRepository.save(user);
|
||||||
|
return getAuthToken(user.getUsername(), generatedPassword);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -140,4 +180,15 @@ public class AuthorizationService {
|
|||||||
return new String(base64.encode(mac.doFinal(base.toString().getBytes(
|
return new String(base64.encode(mac.doFinal(base.toString().getBytes(
|
||||||
ENC))), ENC).trim();
|
ENC))), ENC).trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getAuthToken(String username, String password) throws IOException {
|
||||||
|
HttpClient httpClient = HttpClientBuilder.create().build();
|
||||||
|
HttpPost request = new HttpPost("http://localhost:8080/login");
|
||||||
|
StringEntity params = new StringEntity("{\"username\":\"" + username + "\",\"password\":\"" + password + "\"} ");
|
||||||
|
request.addHeader("content-type", "application/json");
|
||||||
|
request.setEntity(params);
|
||||||
|
HttpResponse httpResponse = httpClient.execute(request);
|
||||||
|
String auth = httpResponse.getFirstHeader("authorization").getValue();
|
||||||
|
return auth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package studycave.studycaverestservice.utils;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
public class PasswordGenerator {
|
||||||
|
|
||||||
|
private static SecureRandom random = new SecureRandom();
|
||||||
|
|
||||||
|
|
||||||
|
public static final String ALPHA_CAPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
public static final String ALPHA = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
public static final String NUMERIC = "0123456789";
|
||||||
|
public static final String SPECIAL_CHARS = "!@#$%^&*_=+-/";
|
||||||
|
|
||||||
|
public static String generatePassword(int len, String dic) {
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
int index = random.nextInt(dic.length());
|
||||||
|
result.append(dic.charAt(index));
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user