使用 Spring Security OAuth2 和 Vaadin flow 21 登录
Login with Spring Security OAuth2 and Vaadin flow 21
我正在尝试为我的 Discord Bot 创建一个 Web 界面,并且很想添加一个“使用 Discord 登录”的方法。我创建了两个视图来测试 OAuth 登录系统。
第一个视图是索引/主页视图,其中包含“使用 discord 登录”按钮。
@PageTitle("Home")
@Route(value = "")
@AnonymousAllowed
public class HomeView extends VerticalLayout {
private final OAuth2AuthorizedClientService clientService;
public HomeView(OAuth2AuthorizedClientService clientService) {
this.clientService = clientService;
setSpacing(false);
setPadding(false);
add(navbar());
add(body());
}
private Component navbar() {
HorizontalLayout root = new HorizontalLayout();
root.setWidthFull();
root.setAlignItems(Alignment.CENTER);
Span name = new Span("Unity");
name.getStyle().set("padding-left", "1rem");
root.add(name);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof OAuth2AuthenticationToken)) {
Button loginButton = new Button();
Image discordLogo = new Image("images/discord.svg", "discord_logo.png");
discordLogo.getStyle().set("padding-top", "0.5rem");
loginButton.setIcon(discordLogo);
loginButton.setText("Login with Discord");
loginButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
loginButton.getStyle().set("padding-right", "1rem");
loginButton.addClassName("toolbar");
Anchor anchor = new Anchor("/oauth2/authorization/discord", loginButton);
anchor.getElement().setAttribute("router-ignore", true);
root.add(anchor);
} else {
Notification.show("Logged In");
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
OAuth2AuthorizedClient client = this.clientService.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(), token.getName());
String accessToken = client.getAccessToken().getTokenValue();
Notification.show("Logged in with token: " + accessToken);
}
root.setFlexGrow(1, name);
root.addClassNames("contrast-5pct");
return root;
}
private Component body() {
VerticalLayout root = new VerticalLayout();
Image img = new Image("images/empty-plant.png", "placeholder plant");
img.setWidth("200px");
root.add(img);
root.add(new H2("This place intentionally left empty"));
root.add(new Paragraph("It’s a place where you can grow your own UI "));
root.setSizeFull();
root.setJustifyContentMode(JustifyContentMode.CENTER);
root.setDefaultHorizontalComponentAlignment(Alignment.CENTER);
root.getStyle().set("text-align", "center");
return root;
}
}
另一个视图是用户认证成功后的视图
@Route("test")
public class TestView extends VerticalLayout {
public TestView() {
add("It Works! :D");
}
}
我当前的 spring oauth 配置如下所示:
spring:
security:
oauth2:
client:
registration:
discord:
client-id: <id>
client-secret: <secret>
clientAuthenticationMethod: post
authorizationGrantType: authorization_code
scope:
- identify
- guilds
redirectUri: "{baseUrl}/login/oauth2/callback/{registrationId}"
clientName: Discord-Client
provider:
discord:
authorizationUri: https://discordapp.com/api/oauth2/authorize
tokenUri: https://discordapp.com/api/oauth2/token
userInfoUri: https://discordapp.com/api/users/@me
usernameAttribute: username
我的 Spring 安全配置如下所示:
@Configuration
public class SecurityConfig extends VaadinWebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth2/authorization/discord", "/login/oauth2/callback/**").permitAll();
http.oauth2Login(oauth -> {
oauth.defaultSuccessUrl("/test");
})
.logout(logout -> {
logout.logoutSuccessUrl("/");
});
super.configure(http);
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring().antMatchers(
"/images/**"
);
}
@Bean
public RestOperations restOperations() {
return new RestTemplate();
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
我已经尝试实施此 post 中的解决方案: 但它一直将我重定向到主页视图并且用户未通过身份验证。
我是否遗漏了对用户进行身份验证的内容!?
提前感谢您的帮助!
我的问题已经解决了。我的 redirectUri 错了^^"
将它从 {baseUrl}/login/oauth2/callback/{registrationId}
更改为 {baseUrl}/login/oauth2/code/{registrationId}
后,它没有任何问题
我正在尝试为我的 Discord Bot 创建一个 Web 界面,并且很想添加一个“使用 Discord 登录”的方法。我创建了两个视图来测试 OAuth 登录系统。
第一个视图是索引/主页视图,其中包含“使用 discord 登录”按钮。
@PageTitle("Home")
@Route(value = "")
@AnonymousAllowed
public class HomeView extends VerticalLayout {
private final OAuth2AuthorizedClientService clientService;
public HomeView(OAuth2AuthorizedClientService clientService) {
this.clientService = clientService;
setSpacing(false);
setPadding(false);
add(navbar());
add(body());
}
private Component navbar() {
HorizontalLayout root = new HorizontalLayout();
root.setWidthFull();
root.setAlignItems(Alignment.CENTER);
Span name = new Span("Unity");
name.getStyle().set("padding-left", "1rem");
root.add(name);
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!(authentication instanceof OAuth2AuthenticationToken)) {
Button loginButton = new Button();
Image discordLogo = new Image("images/discord.svg", "discord_logo.png");
discordLogo.getStyle().set("padding-top", "0.5rem");
loginButton.setIcon(discordLogo);
loginButton.setText("Login with Discord");
loginButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
loginButton.getStyle().set("padding-right", "1rem");
loginButton.addClassName("toolbar");
Anchor anchor = new Anchor("/oauth2/authorization/discord", loginButton);
anchor.getElement().setAttribute("router-ignore", true);
root.add(anchor);
} else {
Notification.show("Logged In");
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) authentication;
OAuth2AuthorizedClient client = this.clientService.loadAuthorizedClient(token.getAuthorizedClientRegistrationId(), token.getName());
String accessToken = client.getAccessToken().getTokenValue();
Notification.show("Logged in with token: " + accessToken);
}
root.setFlexGrow(1, name);
root.addClassNames("contrast-5pct");
return root;
}
private Component body() {
VerticalLayout root = new VerticalLayout();
Image img = new Image("images/empty-plant.png", "placeholder plant");
img.setWidth("200px");
root.add(img);
root.add(new H2("This place intentionally left empty"));
root.add(new Paragraph("It’s a place where you can grow your own UI "));
root.setSizeFull();
root.setJustifyContentMode(JustifyContentMode.CENTER);
root.setDefaultHorizontalComponentAlignment(Alignment.CENTER);
root.getStyle().set("text-align", "center");
return root;
}
}
另一个视图是用户认证成功后的视图
@Route("test")
public class TestView extends VerticalLayout {
public TestView() {
add("It Works! :D");
}
}
我当前的 spring oauth 配置如下所示:
spring:
security:
oauth2:
client:
registration:
discord:
client-id: <id>
client-secret: <secret>
clientAuthenticationMethod: post
authorizationGrantType: authorization_code
scope:
- identify
- guilds
redirectUri: "{baseUrl}/login/oauth2/callback/{registrationId}"
clientName: Discord-Client
provider:
discord:
authorizationUri: https://discordapp.com/api/oauth2/authorize
tokenUri: https://discordapp.com/api/oauth2/token
userInfoUri: https://discordapp.com/api/users/@me
usernameAttribute: username
我的 Spring 安全配置如下所示:
@Configuration
public class SecurityConfig extends VaadinWebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/oauth2/authorization/discord", "/login/oauth2/callback/**").permitAll();
http.oauth2Login(oauth -> {
oauth.defaultSuccessUrl("/test");
})
.logout(logout -> {
logout.logoutSuccessUrl("/");
});
super.configure(http);
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
web.ignoring().antMatchers(
"/images/**"
);
}
@Bean
public RestOperations restOperations() {
return new RestTemplate();
}
@Bean
@Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
}
我已经尝试实施此 post 中的解决方案:
我是否遗漏了对用户进行身份验证的内容!?
提前感谢您的帮助!
我的问题已经解决了。我的 redirectUri 错了^^"
将它从 {baseUrl}/login/oauth2/callback/{registrationId}
更改为 {baseUrl}/login/oauth2/code/{registrationId}
后,它没有任何问题