Compare commits
2 Commits
cff3c4a584
...
25b0b34b8d
Author | SHA1 | Date | |
---|---|---|---|
25b0b34b8d | |||
ae72015cdd |
@ -1,10 +1,10 @@
|
|||||||
package djmil.cordacheckers;
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
import java.security.Principal;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
@ -32,9 +32,9 @@ public class ApiController {
|
|||||||
* @return a Json list of active games
|
* @return a Json list of active games
|
||||||
*/
|
*/
|
||||||
@GetMapping("/api/activegames")
|
@GetMapping("/api/activegames")
|
||||||
public ResponseEntity<String> dashboard(Principal principal) {
|
public ResponseEntity<String> dashboard(@AuthenticationPrincipal ApiUserDetails user) {
|
||||||
|
|
||||||
return ResponseEntity.ok("{ \"ActiveGames\" : [\"game\", \"GAME\", \""+principal.getName()+ "\" ] }" );
|
return ResponseEntity.ok("{ \"ActiveGames\" : [\"game\", \"GAME\", \""+user.getShortHash()+ "\" ] }" );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
public class ApiUserDetails extends User {
|
||||||
|
private final String shortHash;
|
||||||
|
|
||||||
|
public ApiUserDetails(UserDetails user, String shortHash) {
|
||||||
|
super(user.getUsername(), user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(), user.getAuthorities());
|
||||||
|
|
||||||
|
this.shortHash = shortHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getShortHash() {
|
||||||
|
return this.shortHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApiUserDetailsService implements UserDetailsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private PasswordEncoder encoder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
ApiUserShortHashService apiUserShortHash;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiUserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
// Load user from database
|
||||||
|
// User user = userRepository.findByUsername(username);
|
||||||
|
|
||||||
|
// if (user == null) {
|
||||||
|
// throw new UsernameNotFoundException("User not found");
|
||||||
|
// }
|
||||||
|
|
||||||
|
System.out.println("Load user "+username);
|
||||||
|
|
||||||
|
User.UserBuilder users = User.builder();
|
||||||
|
|
||||||
|
UserDetails alice = users
|
||||||
|
.username(username)
|
||||||
|
.password(encoder.encode("qaz123"))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
ApiUserDetails apiUser = new ApiUserDetails(alice, apiUserShortHash.getShortHashBy(username));
|
||||||
|
|
||||||
|
return apiUser;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.naming.InvalidNameException;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import djmil.cordacheckers.cordaclient.CordaClient;
|
||||||
|
import djmil.cordacheckers.cordaclient.pojo.virtualNodes;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ApiUserShortHashService {
|
||||||
|
static final Locale locale = Locale.getDefault();
|
||||||
|
|
||||||
|
Map<String, String> apiUserShortHashMap;
|
||||||
|
|
||||||
|
ApiUserShortHashService(CordaClient client) {
|
||||||
|
this.apiUserShortHashMap = setApiUserShortHashMap(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> setApiUserShortHashMap(CordaClient client) {
|
||||||
|
Map<String, String> map = new HashMap<>();
|
||||||
|
|
||||||
|
List<virtualNodes> vNodesList = client.getVirtualnode();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (virtualNodes vNode : vNodesList) {
|
||||||
|
var identity = vNode.holdingIdentity();
|
||||||
|
|
||||||
|
if (identity.isPlayer()) {
|
||||||
|
map.put(identity.getName().toLowerCase(locale), identity.shortHash());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (InvalidNameException e) {
|
||||||
|
// TODO: logs
|
||||||
|
System.out.println("Unable to get ShorHash map for vNode: "+e.getExplanation());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("ApiUserShortHashMap " + map);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getShortHashBy(String apiUserName) {
|
||||||
|
return this.apiUserShortHashMap.get(apiUserName.toLowerCase(locale));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.security.authentication.AuthenticationProvider;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CustomAuthenticationProvider implements AuthenticationProvider {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Lazy
|
||||||
|
private PasswordEncoder encoder;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ApiUserDetailsService userDetailsService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||||
|
String username = authentication.getName();
|
||||||
|
String password = authentication.getCredentials().toString();
|
||||||
|
|
||||||
|
ApiUserDetails user = userDetailsService.loadUserByUsername(username);
|
||||||
|
|
||||||
|
return checkPassword(user, password);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supports(Class<?> aClass) {
|
||||||
|
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Authentication checkPassword(ApiUserDetails user, String rawPassword) {
|
||||||
|
if (encoder.matches(rawPassword, user.getPassword())) {
|
||||||
|
return new UsernamePasswordAuthenticationToken(user, user.getPassword(), user.getAuthorities());
|
||||||
|
} else {
|
||||||
|
throw new BadCredentialsException("Bad credentials");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,38 +1,59 @@
|
|||||||
package djmil.cordacheckers;
|
package djmil.cordacheckers;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||||
import org.springframework.security.core.userdetails.User;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
|
||||||
|
import static org.springframework.security.config.Customizer.withDefaults;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableWebSecurity
|
||||||
public class SecurityConfig {
|
public class SecurityConfig {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
PasswordEncoder passwordEncoder() {
|
PasswordEncoder passwordEncoder() {
|
||||||
return new BCryptPasswordEncoder();
|
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Autowired
|
||||||
UserDetailsService hardcodedCordaUsers(PasswordEncoder passwordEncoder) {
|
CustomAuthenticationProvider authenticationProvider;
|
||||||
User.UserBuilder users = User.builder();
|
|
||||||
|
|
||||||
UserDetails alice = users
|
@Autowired
|
||||||
.username("alice")
|
public void configure(AuthenticationManagerBuilder auth) throws Exception {
|
||||||
.password(passwordEncoder.encode("qaz123"))
|
auth.authenticationProvider(authenticationProvider);
|
||||||
.build();
|
|
||||||
|
|
||||||
UserDetails bob = users
|
|
||||||
.username("bob")
|
|
||||||
.password(passwordEncoder.encode("qaz123"))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
return new InMemoryUserDetailsManager(alice, bob);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
|
||||||
|
// http
|
||||||
|
// .authorizeRequests(authorizeRequests ->
|
||||||
|
// authorizeRequests.anyRequest().authenticated());
|
||||||
|
// .formLogin(withDefaults());
|
||||||
|
// return http.build();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Bean
|
||||||
|
// UserDetailsService hardcodedCordaUsers(PasswordEncoder passwordEncoder) {
|
||||||
|
// User.UserBuilder users = User.builder();
|
||||||
|
|
||||||
|
// UserDetails alice = users
|
||||||
|
// .username("alice")
|
||||||
|
// .password(passwordEncoder.encode("qaz123"))
|
||||||
|
// .build();
|
||||||
|
|
||||||
|
// UserDetails bob = users
|
||||||
|
// .username("bob")
|
||||||
|
// .password(passwordEncoder.encode("qaz123"))
|
||||||
|
// .build();
|
||||||
|
|
||||||
|
// return new InMemoryUserDetailsManager(alice, bob);
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"x500Name" : "CN=Alice, OU=Test Dept, O=R3, L=London, C=GB",
|
"x500Name" : "CN=Alice, OU=Player, O=Checkers, L=Zug, C=CH",
|
||||||
"cpi" : "MyCorDapp"
|
"cpi" : "MyCorDapp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x500Name" : "CN=Bob, OU=Test Dept, O=R3, L=London, C=GB",
|
"x500Name" : "CN=Bob, OU=Player, O=Checkers, L=Kviv, C=UA",
|
||||||
"cpi" : "MyCorDapp"
|
"cpi" : "MyCorDapp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x500Name" : "CN=Charlie, OU=Test Dept, O=R3, L=London, C=GB",
|
"x500Name" : "CN=Charlie, OU=Player, O=Checkers, L=London, C=GB",
|
||||||
"cpi" : "MyCorDapp"
|
"cpi" : "MyCorDapp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"x500Name" : "CN=Dave, OU=Test Dept, O=R3, L=London, C=GB",
|
"x500Name" : "CN=Kumar, OU=Player, O=Checkers, L=Mumbai, C=IN",
|
||||||
"cpi" : "MyCorDapp"
|
"cpi" : "MyCorDapp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user