spring-boot: 2.1.4.RELEASE
spring-security-oauth3: 2.3.3.RELEASE (Wenn Sie den Quellcode verwenden möchten, ändern Sie diese Versionsnummer nicht nach Belieben, da die Schreibmethode dies ist anders als ab 2.4)
mysql: 5.7
Die Front-End-Seite wird vorerst nicht zum Andocken verwendet eine Seitenanzeige
1. Greifen Sie auf die offene Schnittstelle http://localhost:7000/open/hello zu
2. Greifen Sie auf die geschützte Schnittstelle http://localhost:7000/admin/user/info zu
3. Holen Sie sich das Token, nachdem Sie sich angemeldet haben. Nach dem Zugriff wurden die aktuell angemeldeten Benutzerinformationen erfolgreich zurückgegeben.
Es wird später einen Artikel über SpringCloud + Oauth3 geben, Gateway-Authentifizierung
Lassen Sie uns über einige Punkte sprechen
1. Dynamische Berechtigungen für die Interceptor-Konfiguration
Erstellen Sie eine neue MySecurityFilter-Klasse, erben Sie AbstractSecurityInterceptor und implementieren Sie die FilterschnittstelleInitialisierung, benutzerdefinierter Zugriffsentscheidungsmanager
@PostConstruct public void init(){ super.setAuthenticationManager(authenticationManager); super.setAccessDecisionManager(myAccessDecisionManager); }
Benutzerdefinierter Filter ruft sichere Metadatenquelle auf
@Override public SecurityMetadataSource obtainSecurityMetadataSource() { return this.mySecurityMetadataSource; }
Werfen wir zunächst einen Blick auf den Kerncode des benutzerdefinierten Filters, der sichere Metadatenquelle aufruft
Der folgende Code wird verwendet, um die Berechtigungen (Rollen) zu erhalten ) erforderlich, damit die aktuelle Anfrage eingeht
rrreeWerfen wir einen Blick auf den Kerncode des benutzerdefinierten Zugriffsentscheidungsmanagers. Dieser Code wird hauptsächlich verwendet, um den aktuell angemeldeten Benutzer zu bestimmen (die Rolle, die der aktuell angemeldete Benutzer besitzt). 2. Die benutzerdefinierte Authentifizierungsausnahme gibt ein gemeinsames Ergebnis zurück. Warum ist dies nicht erforderlich? -Ende, um den durch den Authentifizierungsfehler zurückgegebenen Inhalt zu verstehen. Er kann nicht einheitlich interpretiert werden. Schauen wir uns also ohne weiteres die Rückgabesituation ohne Konfiguration und Konfiguration an. (1) Vor der Anpassung, wenn Sie kein Token mitbringen Um auf die geschützte API-Schnittstelle zuzugreifen, sieht das zurückgegebene Ergebnis so aus
(2) Legen wir fest, dass nach der Rückkehr der Authentifizierungsschnittstelle zur Schnittstelle Folgendes angezeigt wird: Ist es für uns besser, den Benutzer zu verarbeiten und aufzufordern?
Okay, schauen wir uns an, wohin wir gehen sollen.
Unser Ressourcenserver OautyResourceConfig schreibt den folgenden Teil des Codes neu, um das von der Authentifizierungsausnahme zurückgegebene Ergebnis anzupassen. Sie können auf diesen https verweisen: //www.yisu.com/article/131668.htm
/** * 获得当前请求所需要的角色 * @param object * @return * @throws IllegalArgumentException */ @Override public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException { String requestUrl = ((FilterInvocation) object).getRequestUrl(); if (IS_CHANGE_SECURITY) { loadResourceDefine(); } if (requestUrl.indexOf("?") > -1) { requestUrl = requestUrl.substring(0, requestUrl.indexOf("?")); } UrlPathMatcher matcher = new UrlPathMatcher(); List<Object> list = new ArrayList<>(); //无需权限的,直接返回 list.add("/oauth/**"); list.add("/open/**"); if(matcher.pathsMatchesUrl(list,requestUrl)) return null; Set<String> roleNames = new HashSet(); for (Resc resc: resources) { String rescUrl = resc.getResc_url(); if (matcher.pathMatchesUrl(rescUrl, requestUrl)) { if(resc.getParent_resc_id() != null && resc.getParent_resc_id().intValue() == 1){ //默认权限的则只要登录了,无需权限匹配都可访问 roleNames = new HashSet(); break; } Map map = new HashMap(); map.put("resc_id", resc.getResc_id()); // 获取能访问该资源的所有权限(角色) List<RoleRescDTO> roles = roleRescMapper.findAll(map); for (RoleRescDTO rr : roles) roleNames.add(rr.getRole_name()); } } Set<ConfigAttribute> configAttributes = new HashSet(); for(String roleName:roleNames) configAttributes.add(new SecurityConfig(roleName)); log.debug("【所需的权限(角色)】:" + configAttributes); return configAttributes; }
3. Holen Sie sich den aktuell angemeldeten Benutzer
Der erste Schritt: Verwenden Sie JWT, um die Benutzerinformationen zu übertragen, und analysieren Sie sie dann, nachdem Sie das Token erhalten habenNoch keine Erklärung
Die zweite: Schreiben Sie einen SecurityUser, um die UserDetails-Schnittstelle zu implementieren (dieses Projekt wird in verwendet)
Die ursprüngliche UserDetails-Schnittstelle hat nur Benutzernamen und Passwort. Hier fügen wir den Benutzer in unserem System hinzu
@Override public void decide(Authentication authentication, Object o, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException { if(configAttributes == null){ //属于白名单的,不需要权限 return; } Iterator<ConfigAttribute> iterator = configAttributes.iterator(); while (iterator.hasNext()){ ConfigAttribute configAttribute = iterator.next(); String needPermission = configAttribute.getAttribute(); for (GrantedAuthority ga: authentication.getAuthorities()) { if(needPermission.equals(ga.getAuthority())){ //有权限,可访问 return; } } } throw new AccessDeniedException("没有权限访问"); }
In BaseController erbt jeder Controller dies und schreibt es in die getUser()-Methode. Solange der Benutzer ein Token für den Zugriff mitbringt, können wir die Informationen des aktuell angemeldeten Benutzers direkt abrufen
@Override public void configure(ResourceServerSecurityConfigurer resources) throws Exception { resources.authenticationEntryPoint(authenticationEntryPoint) //token失效或没携带token时 .accessDeniedHandler(requestAccessDeniedHandler); //权限不足时 }Also nachdem sich der Benutzer angemeldet hat Wenn wir erfolgreich sind, wie wir die Rollensammlung des Benutzers erhalten usw., müssen wir hier die UserDetailsService-Schnittstelle implementieren Sie müssen nur unsere Methode im loginService implementieren und anhand unserer tatsächlichen Geschäftsverarbeitung beurteilen, ob der Benutzer existiert usw.
protected User user; public SecurityUser(User user) { this.user = user; } public User getUser() { return user; }Die Datenbankdatei ist hier
Das obige ist der detaillierte Inhalt vonWie integriert SpringBoot SpringSecurityOauth2, um dynamische Berechtigungsprobleme für die Authentifizierung zu implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!