I have a REST-Client Standalone Desktop-Application in which I can enter a URL and can choose what kind of REST Method I want to execute (POST, GET, PUT etc.)
the client primarily serves the function to send a Body-Message (XML-Format). inside the message all the necessary information to handle the message is contained.
the client also has a Basic authenticator so each Request is also sending a Username and password.
With the help of the Delphi XE8 Application Wizard I created a simple Standalone Firemonkey REST-Server with Authentication and Authorization.
When I send a Request from the Client-Application then my Server is able to recieve that Request inside the "WebModuleDefaultAction"-function which has been added by the Wizard.
What I would like to know is wether or not this is the proper place to check the Authorization of the Request for legitimicy.
It would look like this:
procedure TWebModule1.WebModuleDefaultAction(Sender: TObject; Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
s:string;
Username:string;
Password:String;
begin
s:=Copy(Request.Authorization,7,length(Request.Authorization)-6);
s:=TNetEncoding.Base64.Decode(s);
if (Username='JohnDoe') and (Password='MyPassword') then
begin
if (Request.InternalPathInfo='') or (Request.InternalPathInfo='/') then Response.Content:=ReverseString.Content
else if (Request.InternalPathInfo='ShowContent') or (Request.InternalPathInfo='/ShowContent') then Response.Content:=PP_ShowContent.Content
else Response.SendRedirect(Request.InternalScriptName + '/');
handled:=true;
end
else
begin
Response.Content:='Unauthorized';
handled:=false;
end;
end;
The user-check is static just for now, as the authorization is meant to be presented as a proof of concept.
However, if I do Authorization like this then I expect this function will grow way too big someday and I also miss out on ServerRoles. Unfortunately I am not versed enough in the topic of REST development to know what the proper way to do anything is.
I have seen that there is also an Authentication Manager that has been added by the Wizard. But as before I don't know what to do with it.
Try to use the component TDSAuthenticationManager connected with your TDSServer.
The component TDSAuthenticationManager has a event called AuthenticationManager that is called before create user session. If your variable "valid" is true in the end, the user will authenticate.
See this https://edn.embarcadero.com/br/article/41267
and this https://www.embarcadero.com/images/dm/technical-papers/rest-servers-in-delphi-xe-using-datasnap.pdf
Related
I want Keycloak to send an e-mail to a user whenever a user is blocked due to too many failed login attempts (see section Realm Settings -> Security defenses -> Brute force detection).
The event in question has the following properties:
Error (org.keycloak.events.Event#getError) = user_temporarily_disabled
Type (org.keycloak.events.Event#getType) = LOGIN_ERROR
How can I do that, i. e. make Keycloak send an e-mail to the user when such event occurs?
Known ways to implement it
One obvious way to do it is to write a class that implements the org.keycloak.events.EventListenerProvider interface, detect the event in its onEvent method and trigger sending of the e-mail at some custom server (i. e. send a request to that server and it will contact an SMTP server).
Second is a variation: Detect the event in the same method and somehow make Keycloak send the e-mail using Keycloak SMTP settings ("Realm settings -> Email -> Connection & Authentication").
The screenshot in this answer made met think (possibly wrongly) that there may be a way to make Keycloak send emails upon the occurrence of certain events "out of the box," i. e. without writing custom event listeners.
Update 1: If someone else wants to do this, I recommend to look at this answer. The code below worked for me.
RealmModel realm = this.model.getRealm(event.getRealmId());
UserModel user = this.session.users().getUserById(event.getUserId(), realm);
if (user != null && user.getEmail() != null) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>" + user.getEmail());
org.keycloak.email.DefaultEmailSenderProvider senderProvider = new org.keycloak.email.DefaultEmailSenderProvider(session);
try {
senderProvider.send(session.getContext().getRealm().getSmtpConfig(), user, "test", "body test",
"html test");
} catch (EmailException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Keycloak does indeed support sending emails for events out of the box. However, it can only be configured by event (LOGIN_ERROR), and not by further filtered types (user_temporarily_disabled).
For this, you will need to implement your own EventListener, but it should be easy to heavily copy code from Keycloak's existing EmailEventListener, which you can find here: https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/events/email/EmailEventListenerProvider.java
In there, you'd change the implementation of L59 in onEvent(Event event) to check your two conditions (event type and error), rather than checking against some list of configured fixed events. Your event will be added to the currently running transaction, and when the transaction ends (in success or error), Keycloak will send an email via the SMTP settings that are configured in the realm.
If you want to customize the template and subject lines of the email, you'll have to provide your own freemarker templates in src/main/resources/theme-resources/templates/{html,text}. Both the html and text folder need to contain an .ftl file of the same name. Message keys for use in the template and the subject go in src/main/resources/messages/messages_{en,fr,de,...}.properties files.
With the template and messages configured, you can use one of the 2 send(...) methods available in the EmailTemplateProvider class
I'm setting up some authentication in my rails application. Only thing is I want to log in a user based on their credentials with another API.
The application will have to send a POST request with their username and password in the body to the API and if the request is successful then the user authorised.
I'm having trouble trying to do this with devise, I'm just looking for tips you guys have in order to implement this.
Thanks!
Devise allows you to define custom strategies for authentication. You can therefore create a new strategy to handle it. Database Authentication is one of the strategy already defined at Devise. You can check the source here
A rough idea of your strategy could like this.
Create a file at config/initializers/external_authenticatable.rb and define the strategy
require 'devise/strategies/database_authenticatable'
module Devise
module Strategies
class ExternalAuthenticatable < DatabaseAuthenticatable
def authenticate!
resource = password.present? && mapping.to.find_for_database_authentication(authentication_hash)
if validate(resource){ valid_credentials?(resource) }
remember_me(resource)
resource.after_database_authentication
success!(resource)
end
fail(:not_found_in_database) unless resource
end
def valid_credentials?(resource)
request_params = { email: resource.email, password: password }
# Make your post request here and return true false using authentication_hash
end
end
end
end
Now we need to inform devise that we want to use this strategy first before any other defaults. This can be done by editing /config/initializers/devise.rb
config.warden do |manager|
manager.strategies.add(:external, Devise::Strategies::ExternalAuthenticatable)
manager.default_strategies(:scope => :user).unshift :external
end
Restart your Rails application and you are done.
I've been working with Sails since couple of weeks ago, I came from Rails and I don't have any experience working with Node.js.
Now I'm trying to make a robust token authentication using jsonwebtoken.
https://github.com/auth0/node-jsonwebtoken
I followed this guide http://thesabbir.com/how-to-use-json-web-token-authentication-with-sails-js/ and everything worked fine.
I'm able to make a sign up, sign in and then use the token correctly for different actions.
Now, there are some actions where I'd like to use the login user,
something like devise current_user helper.
For example, when creating a comment, this comment should belongs to the current user.
Using Sabbir Ahmed guide, in the line 33 from the isAuthorized.js policy the token gets decrypted so I can get the current user id from there.
So, my question is, what should be the best way to get the current user and be able to use it later in some controller?
For example I tried something like:
# isAuthorized.js line 34, after getting decrypted token
User.findOne({id: token.id}).exec(function findOneCB(err, found){
currentUser = found;
});
But, on this way, because this is an async action I can't use this currentUser in a controller.
I want to store the current user in order to be able to use it later in some controller without repeated the same code in each controller, something like a helper or maybe a service.
The trick is where you place the next(). Since you are making an async call, the control should only be transferred to next policy/ controller once the database action is competed.
You should modify the policy to:
User.findOne({id: token.id}).exec(function findOneCB(err, found){
if(err) next(err);
req.currentUser = found;
next();
});
And you should be able to access the user details in controllers that use isAuthorized policy via req.currentUser
If by
For example, when creating a comment, this comment should belongs to the current user.
what you mean is certain attributes like username, and country etc, rather than querying the database after verification, what you can choose to do is to send these additional attributes to jwToken.issue in api/controllers/UsersController.js
eg.
jwToken.issue({
id: user.id,
username: user.name,
country: user.country
})
How that helps is, you can keep api/policies/isAuthorized.js as is, and in all the controllers that you use in the future, you can access the payload values from as
token.username or token.country
Instead of having to query the database again, thereby saving you valuable response time.
Beware however, of the data you choose to send in the token (you could also send {user:user} if you want to) however, as the secret key or hashing is not required to decrypt the payload as you can figure # jwt.io , you might want to exercise restraint.
I'm trying to run a REST project and have inserted securitytoken and session into my header.
But I get an errormessage telling me that a cookie is missing (since my service needs a cookie to run successful).
I have tried to do this with Groovy:
import com.eviware.soapui.impl.wsdl.support.http.HttpClientSupport
def myCookieStore = HttpClientSupport.getHttpClient().getCookieStore()
import org.apache.http.impl.cookie.BasicClientCookie
def myNewCookie = new BasicClientCookie("mycookiename", "mycookievalue")
myNewCookie.version = 1
myNewCookie.domain = "my domain as IP"
myCookieStore.addCookie(myNewCookie)
But its still throwing me the same errormessage.
Are there any solution to inject a cookie as a header in SoapUI 5.0?
I would have like to add this as a comment, but I don't have 50 reputation yet.
Don't know if you are still working on this, but anyway:
Like Rao says it seems like you want to work in a session with a negotiated token. You can go three ways with this in soapui.
Like you propose: create the cookie and the values from scratch. That would be a good use case when you want to test which values are going to pass and which values or combos thereof will return errors or different kinds of messages.
If you want to test anything else then the headers, then you can load a certificate, go to the authentication link and retrieve your tokens and session IDs from the headers in the Set-Cookies as proposed by Rao.
Option number three, my personal favourite when testing other things than headers, is to trust SoapUI to take care of it. You can do this by setting the test case to remember your session. You can set this setting in the testcase settings menu. It is called something the likes of 'Maintain http session'.
Remark: In soapui you can modularize tests. You could for example make a testcase for the authentication in an 'util' test suite. This because you can then disable the util test suite to prevent it from running as a dead-weight test. You can then call to this testcase anywhere to invoke the authentication procedure. For this to work you have to set the settings for the 'Run Testcase' (it is named somehting like that) to 'transport the http session to and from this test case' and, like before, set the parent testcase to 'Maintain HTTP Session'. More info on modularization: https://www.soapui.org/functional-testing/modularizing-your-tests.html.
For the security certificate import, check this smartbear example: https://www.soapui.org/resources/blog/ws-security-settings.html
I have a Web API app, initialized thusly:
app.UseCookieAuthentication();
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseOAuthBearerTokens(OAuthOptions);
app.UseGoogleAuthentication();
For calls to most controllers, it works great. However, it also requires a bit of javascript before client-side service calls are made:
function getSecurityHeaders() {
var accessToken = sessionStorage["accessToken"] || localStorage["accessToken"];
if (accessToken) {
return { "Authorization": "Bearer " + accessToken };
}
return {};
}
The problem is that we have a certain type of controller (one that accesses files) where no javascript can be run during the call. For example, the call might be to:
http://mysite/mycontroller/file/filename.jpg
...where the value is assigned as the src attribute of an img tag. The call works, but Thread.CurrentPrincipal.Identity is unauthenticated with a null name, so there's currently not a way to enforce security.
I'm new to Web API, so it may be a dumb question, but what's the way around this? What switches do I need to flip to not require javascript to add security headers? I was considering trying to find a way to force an authorization header in an IAuthorizationFilter or something, but I'm not even sure that would work.
So I figured out the solution to my problem.
First, I needed to configure the app to use an authentication type of external cookies thusly:
//the line below is the one I needed to change
app.UseCookieAuthentication(AuthenticationType = DefaultAuthenticationTypes.ExternalCookie);
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseOAuthBearerTokens(OAuthOptions);
app.UseGoogleAuthentication();
Second, it turned out there was a line of code in my WebApiConfig file that was disabling reading the external cookie:
//this line needed to be removed
//config.SuppressDefaultHostAuthentication();
After that, I could see the external cookie from Google, which passed along an email address I could identify the user with.