我尝试构建一个基于Spring Boot(1.2.7.RELEASE)和Vaadin(7.6.3)的应用程序 . 我的问题是我无法将Spring Security与Vaadin集成 . 我想要一个自定义的Vaadin内置的LoginScreen和Spring Security控件 . 我的项目设置如下:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().
exceptionHandling().authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")).accessDeniedPage("/accessDenied")
.and().authorizeRequests()
.antMatchers("/VAADIN/**", "/PUSH/**", "/UIDL/**", "/login", "/login/**", "/error/**", "/accessDenied/**", "/vaadinServlet/**").permitAll()
.antMatchers("/authorized", "/**").fullyAuthenticated();
}
}
这是我的Vaadin登录界面
@SpringUI(path = "/login")
@Title("LoginPage")
@Theme("valo")
public class LoginUI extends UI {
TextField user;
PasswordField password;
Button loginButton = new Button("Login", this::loginButtonClick);
private static final String username = "username";
private static final String passwordValue = "test123";
@Override
protected void init(VaadinRequest request) {
setSizeFull();
user = new TextField("User:");
user.setWidth("300px");
user.setRequired(true);
user.setInputPrompt("Your username");
password = new PasswordField("Password:");
password.setWidth("300px");
password.setRequired(true);
password.setValue("");
password.setNullRepresentation("");
VerticalLayout fields = new VerticalLayout(user, password, loginButton);
fields.setCaption("Please login to access the application");
fields.setSpacing(true);
fields.setMargin(new MarginInfo(true, true, true, false));
fields.setSizeUndefined();
VerticalLayout uiLayout = new VerticalLayout(fields);
uiLayout.setSizeFull();
uiLayout.setComponentAlignment(fields, Alignment.MIDDLE_CENTER);
setStyleName(Reindeer.LAYOUT_BLUE);
setFocusedComponent(user);
setContent(uiLayout);
}
public void loginButtonClick(Button.ClickEvent e) {
//authorize/authenticate user
//tell spring that my user is authenticated and dispatch to my mainUI
}
}
当我启动我的应用程序时,spring会将我重定向到我的登录UI,这很好 .
但我不知道如何根据spring安全机制对用户进行身份验证并调度到我的mainUI .
我也面临着csrf令牌的问题,如果我不禁用csrf我会得到crfs令牌是null异常 . 我找到了很多处理这些问题的例子,但Vaadin没有提供解决方案 .
感谢帮助 .
2 回答
经过一周的奋斗和研究,我得以实现这一目标 . 这是非常令人疲惫的,因为互联网上有很多信息和解决方案,大多数都使用基于xml的配置或基于JSP表单的登录,直到现在我找不到另一个没有xml配置文件的解决方案,使用Vaadin框架创建一个自定义登录页面 .
我无法保证这是最佳做法或最简单的解决方案 . 此外我没有评估它的每一部分,登录机制尽我所能,但也许可能有一些我还没有发现的问题 .
也许它会帮助那些面临同样问题的人,所以我会在这里发布我的答案 .
首先我的securityConfig:
你必须禁用crsf,但这没有问题,因为vaadin有自己的crsf保护 .
此外,您需要允许一些URI,以便vaadin可以访问其资源:
/VAADIN/**
是绝对必要的,我还建议允许/vaadinServlet/**
,/PUSH/**
和/HEARTBEAT/**
,但这取决于您使用的Vaadin的哪些部分 .我的第二个
UserDetailsService
:DaoAuthenticationProvider
使用UserDetails
'loadUserByUserName
方法获取实现UserDetails
接口的类的对象 . 请注意UserDetailsInterface
中描述的每个属性都不能为空,否则后来DaoAuthenticationProvider
会抛出NullPointerException
.我创建了一个实现UserDetails接口的JPA实体:
加上当局实体:
显然,在身份验证工作之前,您必须先将一些用户数据存储在数据库中 .
在Vaadin中,我无法通过使用一个具有不同视图的UI来实现它,因此我最终使用两个UI用于登录,另一个用于主应用程序 .
在Vaadin中,我可以在类注释中设置URI路径:
使用此配置,我的登录屏幕位于
localhost:port/login
,我的主应用程序位于localhost:port/main
.我在loginUI中的button.click方法中以编程方式登录用户:
我希望它能帮助你们中的一些人 .
作为给定方法的替代方案,您还可以依赖vaadin4spring, an 'unofficial' set of extensions to further integrate Vaadin and Spring .
它目前提供two ways来集成Spring Security,它似乎工作正常(即使它们不适合你,代码示例应该给你足够的见解来编写自定义集成代码) .