Vaadin 24 + Spring Boot 3 + Spring Security – 如何通过SOAP端点进行身份验证

huangapple go评论72阅读模式
英文:

Vaadin 24 + Spring Boot 3 + Spring Security - How to Authenticate via a SOAP Endpoint

问题

I'm a total newbie to both Vaadin and Java - so I apologize in advance if I'm asking a question that is totally LAME - or has been answered elsewhere (I have done extensive Google and Stackoverflow searches - and have not been able to find what I need).

SO - I need to authenticate a Vaadin 24 application with Spring 3 using Spring Security against a SOAP endpont.

The rest endpoint takes a username and password - and will return a SOAP response like:

<?xml version="1.0" encoding="UTF-8"?>
<SSOAPI version="2.0">
	<Response>
		<RequestStatusCode>0</RequestStatusCode>
		<RequestStatusMessage>OK</RequestStatusMessage>
		<SSOTokenStr></SSOTokenStr>
		<uid>jdoe</uid>
		<FullName>Doe_John</FullName>
		<IdType>AD</IdType>
		<eMail>jdoe@gmail.com</eMail>
		<UserGroup>Group 1</UserGroup>
		<UserGroup>Group 2</UserGroup>
		<UserGroup>Group 3</UserGroup>
	</Response>
</SSOAPI>

A FAILED response would be:

<?xml version="1.0" encoding="UTF-8"?>
<SSOAPI version="2.0">
	<Response>
		<RequestStatusCode>1326</RequestStatusCode>
		<RequestStatusMessage>Failed : Invalid Credentials</RequestStatusMessage>
		<SSOTokenStr></SSOTokenStr>
		<uid>rcusickk</uid>
		<FullName></FullName>
		<MednetUserGroup></MednetUserGroup>
	</Response>
</SSOAPI>

I have a basic Vaadin login view that looks like this:

@Route("login")
public class LoginView extends Composite<LoginOverlay>{

    
    public LoginView(){
        LoginOverlay loginOverlay = getContent();
        loginOverlay.setTitle("My App");
        loginOverlay.setDescription("Log in requires an account");
        loginOverlay.setOpened(true);
        
        loginOverlay.addLoginListener(event -> {
            try{
                
                authService.authenticate(event.getUsername(), event.getPassword());
                UI.getCurrent().navigate("home");
                
            } catch (Exception e) {
                
                
            }
            
        });
    }
}

I would like to just setup a service ("authService" above) that will allow me to connect to a URL, pass in URL params with userName and password (via POST) and then get back a response that I can then just parse and and if there is Request Status Code > 0 - to return the Request Status code.

There are 1,000,000 examples of using a database to authenticate - but I need to authenticate via a SOAP endpoint URL.

Any hints to the Yellow Brick Road would be appreciated!

I've tried to create an "Auth Service" - so I can just make sure it passed in the username and password:

class AuthService {
    
    public class AuthException extends Exception {
        
    }
    
    public AuthService(){
        
    }
    
    public void authenticate(String username, String password) {
        
        System.out.println("User: " + username + ", pass: " + password);
    }
}

and I also tried to reference the service via the login view:

@Route("login")
public class LoginView extends Composite<LoginOverlay>{

    
    public LoginView(AuthService authService){
        LoginOverlay loginOverlay = getContent();
        loginOverlay.setTitle("My App");
        loginOverlay.setDescription("Log in requires an account");
        loginOverlay.setOpened(true);
        
        loginOverlay.addLoginListener(event -> {
            try{
                
                authService.authenticate(event.getUsername(), event.getPassword());
                UI.getCurrent().navigate("home");
                
            } catch (Exception e) {
                
                
            }
            
        });
    }
}

RESULT ERROR when displaying the LoginView:

There was an exception while trying to navigate to 'login' with the root cause 'org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.application.views.login.AuthService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.application.views.login.LoginView': Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'com.example.application.views.login.AuthService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

(Note: The original code includes HTML escape sequences for characters like "&", "<", and ">", which have been replaced with their respective characters in this translation.)

英文:

I'm a total newbie to both Vaadin and Java - so I apologize in advance if I'm asking a question that is totally LAME - or has been answered elsewhere (I have done extensive Google and Stackoverflow searches - and have not been able to find what I need).

SO - I need to authenticate a Vaadin 24 application with Spring 3 using Spring Security against a SOAP endpont.

The rest endpoint takes a username and password - and will return a SOAP response like:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;SSOAPI version=&quot;2.0&quot;&gt;
	&lt;Response&gt;
		&lt;RequestStatusCode&gt;0&lt;/RequestStatusCode&gt;
		&lt;RequestStatusMessage&gt;OK&lt;/RequestStatusMessage&gt;
		&lt;SSOTokenStr&gt;&lt;/SSOTokenStr&gt;
		&lt;uid&gt;jdoe&lt;/uid&gt;
		&lt;FullName&gt;Doe_John&lt;/FullName&gt;
		&lt;IdType&gt;AD&lt;/IdType&gt;
		&lt;eMail&gt;jdoe@gmail.com&lt;/eMail&gt;
		&lt;UserGroup&gt;Group 1&lt;/UserGroup&gt;
		&lt;UserGroup&gt;Group 2&lt;/UserGroup&gt;
		&lt;UserGroup&gt;Group 3&lt;/UserGroup&gt;
	&lt;/Response&gt;
&lt;/SSOAPI&gt;

A FAILED response would be:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;SSOAPI version=&quot;2.0&quot;&gt;
	&lt;Response&gt;
		&lt;RequestStatusCode&gt;1326&lt;/RequestStatusCode&gt;
		&lt;RequestStatusMessage&gt;Failed : Invalid Credentials&lt;/RequestStatusMessage&gt;
		&lt;SSOTokenStr&gt;&lt;/SSOTokenStr&gt;
		&lt;uid&gt;rcusickk&lt;/uid&gt;
		&lt;FullName&gt;&lt;/FullName&gt;
		&lt;MednetUserGroup&gt;&lt;/MednetUserGroup&gt;
	&lt;/Response&gt;
&lt;/SSOAPI&gt;

I have a basic Vaadin login view that looks like this:

@Route(&quot;login&quot;)
public class LoginView extends Composite&lt;LoginOverlay&gt;{

    
    public LoginView(){
        LoginOverlay loginOverlay = getContent();
        loginOverlay.setTitle(&quot;My App&quot;);
        loginOverlay.setDescription(&quot;Log in requires an account&quot;);
        loginOverlay.setOpened(true);
        
        loginOverlay.addLoginListener(event -&gt; {
            try{
                
                authService.authenticate(event.getUsername(), event.getPassword());
                UI.getCurrent().navigate(&quot;home&quot;);
                
            } catch (Exception e) {
                
                
            }
            
        });
    }
}

I would like to just setup a service ("authService" above) that will allow me to connect to a URL, pass in URL params with userName and password (via POST) and then get back a response that I can then just parse and and if there is Request Status Code > 0 - to return the Request Status code.

There are 1,000,000 examples of using a database to authenticate - but I need to authenticate via a SOAP endpoint URL.

Any hints to the Yellow Brick Road would be appreciated!

I've tried to create an "Auth Service" - so I can just make sure it passed in the username and password:

class AuthService {
    
    public class AuthException extends Exception {
        
    }
    
    public AuthService(){
        
    }
    
    public void authenticate(String username, String password) {
        
        System.out.println(&quot;User: &quot; + username + &quot;, pass: &quot; + password);
    }
}

and I also tried to reference the service via the login view:

@Route(&quot;login&quot;)
public class LoginView extends Composite&lt;LoginOverlay&gt;{

    
    public LoginView(AuthService authService){
        LoginOverlay loginOverlay = getContent();
        loginOverlay.setTitle(&quot;My App&quot;);
        loginOverlay.setDescription(&quot;Log in requires an account&quot;);
        loginOverlay.setOpened(true);
        
        loginOverlay.addLoginListener(event -&gt; {
            try{
                
                authService.authenticate(event.getUsername(), event.getPassword());
                UI.getCurrent().navigate(&quot;home&quot;);
                
            } catch (Exception e) {
                
                
            }
            
        });
    }
}

RESULT ERROR when displaying the LoginView:

There was an exception while trying to navigate to &#39;login&#39; with the root cause &#39;org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type &#39;com.example.application.views.login.AuthService&#39; available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}&#39;
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name &#39;com.example.application.views.login.LoginView&#39;: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type &#39;com.example.application.views.login.AuthService&#39; available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

答案1

得分: 0

Route 和引用的路由布局是由 Vaadin 自动实例化的,如果您正在使用 Vaadin Spring 支持,它会将该任务委托给常规的 Spring 依赖注入。

您看到的错误是 Spring 无法实例化 AuthService,这是因为您没有配置它参与 DI。在您的 AuthService 上添加一个 @Service 注解,并确保 Spring 能够看到它(例如,将它放在与您的 Application 类相邻或以下的包中)。

这样说吧:如果您想违背 Spring 安全性的规范,我建议根本不要使用它。否则,考虑将您的 AuthService 设为 UserDetailService 并在那里调用您的 SOAP 端点。提到的那些 1,000,000 数据库教程也提供了如何自己查询数据库的指南,这是您放置自己的认证代码的地方。

英文:

Route and referenced router layouts are automatically instantiated by
Vaadin and if you are using the Vaadin Spring support that will delegate
the task to the regular Spring dependency injection.

The error you are seeing is Spring not being able to instantiate
AuthService, which you have not configured to take part in DI. Add
a @Service annotation to your AuthService and make sure Spring can
see it (e.g. put it in a package beside or below your Application
class).

This said: if you want to go against the grain of Spring security, I'd
suggest to not use it at all. Otherwise consider making your
AuthService a UserDetailService and call your SOAP endpoints there.
The mentioned 1.000.000 DB tutorials also have pointers on how to query
the DB yourself and this is the place where you would put your own authn
code.

huangapple
  • 本文由 发表于 2023年6月9日 02:30:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76434745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定