Я разрабатываю приложение (весенняя загрузка для бэкэнда и реакция для внешнего интерфейса) с аутентификацией с Office 365. Но я хочу использовать свою собственную группу и разрешения для пользователей. Например, когда пользователь впервые обращается к / api / auth, я хочу получить информацию из графика Microsoft и сохранить ее в моей БД, а затем защитить свою конечную точку с помощью моих собственных ролей / разрешений.
Итак далеко мне удалось это сделать:
- Когда я go на localhost: 8080 (назад), я перенаправляюсь на портал Azure для аутентификации. Затем я могу получить доступ к своим конечным точкам
- Я могу защитить свои конечные точки с помощью моих собственных ролей
- Когда я go на localhost: 3000 (приложение для реагирования), у меня есть кнопка, которая перенаправляет меня на портал и дайте мне azure токен доступа (спасибо MSAL. js)
Итак, моя проблема в том, что я не могу проверить этот azure токен в моем бэкенде и отправить новый токен сзади наперед для отправки запроса (например, GET / api / users или POST / api / todos). Я думаю, что моя конфигурация и реализация бэкэнда неверны, но я не нашел способа проверить токены и вернуть токен для моего бэкэнда ...
Надеюсь, я понял, engli sh не мой родной язык
Вот мой WebSecurityConfig
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests().antMatchers("/**")
.authenticated()
.and()
.csrf().csrfTokenRepository(csrfTokenRepository()).and()
.addFilterAfter(csrfHeaderFilter(), CsrfFilter.class)
.oauth2Login();
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
@Bean
public HttpFirewall allowUrlEncodedSlashHttpFirewall() {
StrictHttpFirewall firewall = new StrictHttpFirewall();
firewall.setAllowUrlEncodedSlash(true);
return firewall;
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.httpFirewall(allowUrlEncodedSlashHttpFirewall());
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
}
А вот как я защищаю свои конечные точки:
@PreAuthorize("hasPermission(#foo, 'write')")
Конфигурация:
@Configuration
public class AclPermissionEvaluator implements PermissionEvaluator {
@Autowired
private RoleRepository roleRepository;
@Autowired
private SecurityService securityService;
@Override
public boolean hasPermission(final Authentication authentication, final Object privilegeName, final Object privilegeType) {
DefaultOidcUser principal = (DefaultOidcUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
Map<String, Object> userAttributes = principal.getAttributes();
UserInfo userInfo = securityService.getUserInfoByLogin((String) userAttributes.get("unique_name"));
if (userInfo == null || StringUtils.isBlank((CharSequence) privilegeName) || StringUtils.isBlank((CharSequence) privilegeType)) {
return false;
}
for (Permission permission : roleRepository.getByName(userInfo.getRoleName()).getPermissions()) {
if (permission.getPermission().startsWith((String) privilegeName) || permission.getPermission().equals("*")) {
return true;
}
}
return false;
}
//We don't need an implementation of this function for now
@Override
public boolean hasPermission(final Authentication authentication, final Serializable serializable, final String s, final Object o) {
return false;
}
}
Служба безопасности:
@Service
@Transactional
public class SecurityServiceImpl implements SecurityService {
@Autowired private UserRepository userRepo;
@Autowired
private RoleRepository roleRepository;
@Override
public UserInfo getUserInfoByLogin(String username) {
User user = userRepo.getUserByUsername(username);
ModelMapper modelMapper = new ModelMapper();
return modelMapper.map(user, UserInfo.class);
}
}
RoleRepository:
@Repository
public interface RoleRepository extends JpaRepository<Role, Long> {
public Role getByName(String name);
}
И на моем application.yml:
spring:
security:
oauth2:
client:
registration:
azure:
clientId: <my-clientId>
clientSecret: <my-secret>
azure:
activedirectory:
tenant-id: <my-tenant-id>
user-group:
allowed-groups: all
active-directory-groups: all