Symfony 2 - WSSE - FOSUserBundle - FOSRestBundle - Javascript - angularjs

I try to incorporate WSSE Authentification. I have a symfony in back, and an app Ionic - AngularJS in front.
I followed the cookbook about WSSE, and theses tutorials :
http://obtao.com/blog/2013/05/create-rest-api-in-a-symfony-application/
http://obtao.com/blog/2013/06/configure-wsse-on-symfony-with-fosrestbundle/
And
http://obtao.com/blog/2013/09/how-to-use-wsse-in-android-app/
I install WSSE well, i can hash my password in my app with this code:
authentication.hashPassword = function(salt, clearPassword) {
var digest = "";
console.log('==== STARTING HASHING PASSWORD ====');
var salted = null;
if (!salt || salt == "") {
salted = clearPassword;
} else {
salted = clearPassword + "{" + salt + "}";
}
digest = CryptoJS.SHA512(salted);
for (var i=1; i<5000; i++) {
digest = CryptoJS.SHA512(digest.toString(CryptoJS.enc.Latin1)+salted);
}
digest = digest.toString(CryptoJS.enc.Base64);
console.log('==== ENDING HASHING PASSWORD ====');
console.log(digest);
return digest;
};
but i would like to generate header with my hash password ( the last tutorial is coded in java, and i'm a noob in Java)
Is it Possible to compare two hash password if i post my hash password ?
have you any idea to create a header ( or Token ) ?
Thank you for your answer

Your application seems to be based on Ionic Framework. After the "Android application" mentioned in tutorial, we have also tested ionic.
See https://github.com/wallabag/ionic-app (crypto is "handmade", but it will help you for the header part with ionic/angularjs)
In app.js :
$http.defaults.headers.common['x-wsse'] = function() {
return wsse.getHeaderValue(username, encryptedPassword);
};
$http.defaults.headers.common.Authorization = 'profile=UsernameToken';

Related

IdentityServer4.Validation.TokenRequestValidator: Invalid authorization code

I am using Identity Server 4 With Microsoft Blazor application. Authentication process works fine in local. But after deploying changes in azure it was working fine before one week. Suddenly it's started giving some errors and stuck on https://websiteurl.com/signin-oidc page. After checking identity server log I found this error
IdentityServer4.Validation.TokenRequestValidator: Invalid authorization code
Some times it's working and some times getting above error. More than 50% of time i am getting above error.
I tried following code generate custom codeVerifier and add before redirecting to identity server.
if (context.ProtocolMessage.RequestType == OpenIdConnectRequestType.Authentication)
{
// generate code_verifier
var codeVerifier = CryptoRandom.CreateUniqueId(32);
// store codeVerifier for later use
context.Properties.Items.Remove(CODE_VERIFIER_KEY);
context.Properties.Items.Add(CODE_VERIFIER_KEY, codeVerifier);
Logger.Log(LogLevel.Information, CODE_VERIFIER_KEY + ": " + codeVerifier);
// create code_challenge
string codeChallenge;
using (var sha256 = SHA256.Create())
{
var challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
codeChallenge = Base64Url.Encode(challengeBytes);
}
// add code_challenge and code_challenge_method to request
context.ProtocolMessage.Parameters.Remove(CODE_CHALLENGE_KEY);
context.ProtocolMessage.Parameters.Remove(CODE_CHALLENGE_METHOD_KEY);
Logger.Log(LogLevel.Information, CODE_CHALLENGE_KEY + ": " + codeChallenge);
context.ProtocolMessage.Parameters.Add(CODE_CHALLENGE_KEY, codeChallenge);
context.ProtocolMessage.Parameters.Add(CODE_CHALLENGE_METHOD_KEY, "S256");
}
OnAuthorizationCodeReceived = (context) =>
{
// context.Options.
//Add claim if they are
//var claims = new List<Claim> { new Claim(ClaimTypes.Role, "Provider") };
//var appIdentity = new ClaimsIdentity(claims);
//context.Principal.AddIdentity(appIdentity);
// only when authorization code is being swapped for tokens
// only when authorization code is being swapped for tokens
Logger.Log(LogLevel.Information, "OnAuthorizationCodeReceived - " + context.TokenEndpointRequest.Parameters);
if (context.TokenEndpointRequest?.GrantType == OpenIdConnectGrantTypes.AuthorizationCode)
{
// get stored code_verifier, This if condition is never gets executed
if (context.Properties.Items.TryGetValue(CODE_VERIFIER_KEY, out var codeVerifier))
{
// add code_verifier to token request
context.TokenEndpointRequest.Parameters.Add(CODE_VERIFIER_KEY, codeVerifier);
}
}
return Task.CompletedTask;
},

Firebase.resetPassword() password lifetime [duplicate]

This question already has an answer here:
How to extend lifetime of password, generated by ref.resetPassword()?
(1 answer)
Closed 6 years ago.
I'm using angularJS and firebase as backend to create my simple web app.
When .resetPassword() method is called, an email which contains a temporary password is sent to user, so he can login into an app.
According to the following resource, lifetime of the temporary password is 24 hours:
https://www.firebase.com/docs/web/api/firebase/resetpassword.html
So, I have a question - what happens after the temporary password expires? Is it just discarded and an old password can be used again?..
Thanks in advance
Basically you can change the users password, and then email it to him manually.. So lets say when they register to your app it becomes in the following order:
username---
Username
Password
Email
UID
So then when the user clicks on resetPassword you have to generate a random password, and send him a email... So first lets tackle sending the email:
First of register for Mandrill
1. register for Mandrill to get an API key
2. load jQuery
3. use $.ajax to send an email
So this is how it will be layed out :
function randomPassword(){
var length = 8,
charset = "abcdefghijklnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789",
retVal = "";
for (var i = 0, n = charset.length; i < length; ++i) {
retVal += charset.charAt(Math.floor(Math.random() * n));
}
return retVal;
}
Dont forget to add this to your script tag:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
So you can send emails:
And:
$.ajax({
type: “POST”,
url: “https://mandrillapp.com/api/1.0/messages/send.json”,
data: {
‘key’: ‘YOUR API KEY HERE’,
‘message’: {
‘from_email’: ‘YOUR#EMAIL.HERE’,
‘to’: [
{
‘email’: ‘RECIPIENT_NO_1#EMAIL.HERE’,
‘name’: ‘RECIPIENT NAME (OPTIONAL)’,
‘type’: ‘to’
},
{
‘email’: ‘RECIPIENT_NO_2#EMAIL.HERE’,
‘name’: ‘ANOTHER RECIPIENT NAME (OPTIONAL)’,
‘type’: ‘to’
}
],
‘autotext’: ‘true’,
‘subject’: ‘Password generated’,
‘html’: ‘This is your Newly generated password’ + randomPassword
}
}
}).done(function(response) {
console.log(response);
});
More info on the sending email part here
If you are trying to do this only using firebase, that is not possible as frank said here: How to extend lifetime of password, generated by ref.resetPassword()?

'Anonymous user' error after passing data with Angular to Rest

I am a beginner in Angular and Rest and I have a problem. I have a form in Django template and I want to pass data with Angular, receive it with Rest and process it. Angular knows to pass (post) the data by url to:
url(r'^api/nowyPacjent/$', CreateNewPatient.as_view(), name="api_tempPatient"),
The CreateNewPatient class looks like this:
class CreateNewPatient(generics.ListCreateAPIView):
model = TempPatient
queryset = TempPatient.objects.all()
serializer_class = CreateNewPatientSerializer
and the serializer looks like this:
class CreateNewPatientSerializer(serializers.Serializer):
name = serializers.CharField(max_length=30)
surname = serializers.CharField(max_length=70)
phone = serializers.CharField(max_length=15, required=False)
age = serializers.IntegerField(max_value=99, min_value=1, required=False)
company = serializers.PrimaryKeyRelatedField(many=False, queryset=Company.objects.all())
therapyStart = serializers.DateField(required=False)
def create(self, validated_data):
if 'therapyStart' in validated_data:
therapy_start = validated_data['therapyStart']
else:
therapy_start = datetime.date.today()
if 'age' in validated_data:
patient_age = validated_data['age']
else:
patient_age = 1;
if 'phone' in validated_data:
patient_phone = validated_data['phone']
else:
patient_phone = ''
newTempPatient = TempPatient(
name = validated_data['name'],
surname = validated_data['surname'],
company = validated_data['company'],
therapyStart = therapy_start,
age = patient_age,
phone = patient_phone
)
newTempPatient.save()
newPatient = Patient(
name=validated_data['name'],
surname=validated_data['surname'],
phone=patient_phone,
age=patient_age
)
newPatient.save()
user=None
request = self.context.get('request')
if request and hasattr(request,"user"):
user=request.user
newTherapyGroup = TherapyGroup.objects.create(
start = therapy_start,
patient = newPatient,
therapist = Therapist.objects.get(user = user),
company = validated_data['company']
)
newTherapyGroup.save()
return newTempPatient
Everything is fine - after submitting the template form the patient is created - until the code tries to get logged user from the request (just after the last if statement of the serializer). Then I receive the 'AnonymousUser' error and cannot create final model instance. I've tried to pass the data to the Django views and then use the Rest's serializer. However, the error occurred again. I've searched for the answer but nothing was helpful. Please, notice that I don't want to authenticate the logged user but to get data about him.
I think the problem is that Angular somehow loose information about CSRF token and log session and that is the reason of both errors (that is only my assumption).
Below is how Angular config looks like. NewPatientCtrl is responsible for mentioned form and model is one of the form element (and it works fine).
angular.module('pacjent', ['ngMessages', 'ui.bootstrap', 'datetime'])
.constant('companyListApi','http://localhost:8000/finanse/api/list/')
.constant('tempPatientApi','http://localhost:8000/pacjent/api/nowyPacjent/')
.factory('ModelUtils', ModelUtils)
.factory('newPatientFormApi',newPatientFormApi )
.factory('companyApi', companyApi)
.factory('mySharedService', mySharedService)
.controller('PacjentCtrl', PacjentCtrl)
.controller('NewPatientCtrl', NewPatientCtrl)
.controller('ModalInstanceCtrl', ModalInstanceCtrl)
.config(function($interpolateProvider, $httpProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
})
The interesting thing is that this code works perfect on my colleague's system (Windows 7, Chrome) - the user data is gathered perfectly. However, I've tested it on three different systems (Windows 7 x64, Xubuntu 14.04, Ubuntu 14) and several browsers (Firefox, Chromium) on my PCs and the same error occurs.
Thank you a lot for any comments and advice. Sorry also for any non-professional statements.
it is because of this line:
user=request.user
# ...
therapist = Therapist.objects.get(user = user),
you are trying to get a therapist from your database with an Anynomous user in your ORM - it means a user who is not logged in.
you need is_authenticated() in your check:
if request and hasattr(request,"user") and request.user.is_authenticated():
user=request.user
newTherapyGroup = TherapyGroup.objects.create(
start = therapy_start,
patient = newPatient,
therapist = Therapist.objects.get(user=user),
company = validated_data['company']
)
newTherapyGroup.save()

Using OAuth2 with service account on gdata in python

I want to use data.photos.service.PhotosService to push and pull photos from Picasa. I got a service key file XXXXXXXX-privatekey.p12 from Google console and am now trying to authenticate using said key with google.
The documentation for OAUTH2 using appengine has led me to believe that using the following would be of use:
f = file(settings.SITE_ROOT + '/aurora/' + settings.PRIVATE_KEY, 'rb')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials(settings.SERVICE_ACCOUNT_NAME, key, scope = 'http://picasaweb.google.com/data https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile')
http = httplib2.Http()
http = credentials.authorize(http)
service = build("oauth2", "v2", http=http)
user_info = None
try:
user_info = service.userinfo().get().execute()
# neither of these two methods work
#gd_client.SetOAuthInputParameters(signature_method = gdata.auth.OAuthSignatureMethod.RSA_SHA1, consumer_key = "asdfasdfasdf.apps.googleusercontent.com", rsa_key = key, two_legged_oauth = True, requestor_id = user_info.get('email'))
#gd_client.auth_token = gdata.gauth.TwoLeggedOAuthRsaToken(consumer_key = user_info.get('email'), rsa_private_key = key, requestor_id = user_info.get('email'))
except errors.HttpError, e:
logging.error('An error occurred: %s', e)
user_inf0 = {u'verified_email': True, u'id': u'1234', u'name': u'asdfasdfasdf#developer.gserviceaccount.com', u'email': u'asdfasdfasdf#developer.gserviceaccount.com'}
The issue is that either method 1 using SetOAuthInputParameters returns a invalid token, or method 2 returns a 403 restricted.
I am at my wits' end reading through mountains of code that all do regular 3 legged oauth when I really and truly do not want to do it that way. Any ideas/articles I haven't seen yet?
Use gdata.gauth.OAuth2TokenFromCredentials.
auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
gd_client = auth2token.authorize(gd_client)
OAuth2TokenFromCredentials is designed to help you use apiclient and gdata at the same time. Under the covers, it uses the credentials for making sure it has the auth information it needs to perform gdata calls.
Note, if you still get 403, it may be something else entirely. I was using a service account to access a user's data and was getting 403 because I hadn't spec'd the user properly in the SignedJwtAssertionCredentials call.
UPDATE: Here's the basic pattern I used:
from oauth2client.client import SignedJwtAssertionCredentials
credentials = SignedJwtAssertionCredentials(
    "XXXXXXXXXXX#developer.gserviceaccount.com",
    open("keyfile").read(),
    scope=(
    "https://www.googleapis.com/auth/drive",
    "https://spreadsheets.google.com/feeds",
    "https://docs.google.com/feeds"
), # For example.
    sub="user#gmail.com"
)
http = httplib2.Http()
http = credentials.authorize(http) # Not needed? See comment below.
auth2token = gdata.gauth.OAuth2TokenFromCredentials(credentials)
gd_client = gdata.photos.service.PhotosService() # For example.
gd_client = auth2token.authorize(gd_client)
If you are using MFA on your google account, you need to use the consent screen authentication method. With Picassa API, it does not work as is, as the request API is slightly different.
import gdata.gauth
import os
import pickle
import gdata.photos.service
clientid='xxx' # https://console.developers.google.com/apis/credentials
clientsecret='xxx'
Scope='https://picasaweb.google.com/data/'
User_agent='myself'
def GetAuthToken():
if os.path.exists(".token"):
with open(".token") as f:
token = pickle.load(f)
else:
token = gdata.gauth.OAuth2Token(client_id=clientid,client_secret=clientsecret,scope=Scope,user_agent=User_agent)
print token.generate_authorize_url(redirect_uri='urn:ietf:wg:oauth:2.0:oob')
code = raw_input('What is the verification code? ').strip()
token.get_access_token(code)
with open(".token", 'w') as f:
pickle.dump(token, f)
return token
token = GetAuthToken()
gd_client = gdata.photos.service.PhotosService()
old_request = gd_client.request
def request(operation, url, data=None, headers=None):
headers = headers or {}
headers['Authorization'] = 'Bearer ' + token.access_token
return old_request(operation, url, data=data, headers=headers)
gd_client.request = request
photos = gd_client.GetUserFeed(kind='photo', limit='10')
for photo in photos.entry:
print 'Recently added photo title:', photo.title.text

oauth problem( app engine)

i am trying to pull user's documents data from google docs using oauth,
but i cannot understand how to do it
- what's the purpose of oauth_verifier
- how to get the access token secret?
- if i try to use DocsService below, then i have a "server error"
- is there a clear tutorial for this? i cannot find any atm..
String oauth_verifier = req.getParameter("oauth_verifier");
String oauth_token = req.getParameter("oauth_token");
String oauthtokensecret = req.getParameter("oauth_token_secret");
GoogleOAuthParameters oauthparam = new GoogleOAuthParameters();
oauthparam.setOAuthConsumerKey("consumer key");
oauthparam.setOAuthConsumerSecret("secret");
oauthparam.setOAuthToken(oauth_token);
oauthparam.setOAuthTokenSecret(oauthtokensecret);
oauthparam.setOAuthVerifier(oauth_verifier);
OAuthHmacSha1Signer signer = new OAuthHmacSha1Signer();
GoogleOAuthHelper oauthhelper = new GoogleOAuthHelper(signer);
String accesstoken = "";
String accesstokensecret = "";
try {
oauthhelper.getUnauthorizedRequestToken(oauthparam);
accesstoken = oauthhelper.getAccessToken(oauthparam);
accesstokensecret = oauthparam.getOAuthTokenSecret();
// DocsService client = new DocsService("yourCompany-YourAppName-v1");
...
These may not be what you are looking for, since they are OAuth-specific and not google-related, but I found these "Getting started" articles very helpful:
http://oauth.net/documentation/getting-started
Turns out that I need to get the oauth_token_secret and reuse it later.
So (before redirecting user to google login page)
oauthhelper.getUnauthorizedRequestToken(oauthparam);
requesturl = oauthhelper.createUserAuthorizationUrl(oauthparam);
OAuthTokenSecret.tokenSecret = oauthparam.getOAuthTokenSecret();
resp.sendRedirect(requesturl);
Then after the user grants access and we have been redirected to oauth_callback url:
oauthparam.setOAuthToken(oauthtoken);
oauthparam.setOAuthVerifier(oauthverifier);
oauthparam.setOAuthTokenSecret(OAuthTokenSecret.tokenSecret);
oauthhelper.getAccessToken(oauthparam); // access token and access token secret are saved in oauthparam.
// access google service..
GoogleService googleService = new GoogleService( "cp", "test222");
googleService.setOAuthCredentials(oauthparam, signer);
BaseFeed resultFeed = googleService.getFeed(feedUrl, Feed.class);

Resources