Error message: "The SMTP server requires a secure connection or the client was not authenticated." - smtpclient

I have searched other posts and set required things in my gmail account(https://myaccount.google.com/lesssecureapps)
but somehow it still throws exception with the message "The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required. Learn more at"
[HttpPost]
public ActionResult SaveAppointment(Appointment mdl)
{
try
{
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);
smtpClient.Credentials = new System.Net.NetworkCredential("username", "mypass");
smtpClient.UseDefaultCredentials = false;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.EnableSsl = true;
MailMessage mail = new MailMessage();
//Setting From , To and CC
mail.From = new MailAddress("username#gmail.com", "MyWeb Site");
mail.To.Add(new MailAddress("username#gmail.com"));
smtpClient.Send(mail);
return View();
}
catch(Exception ex)
{
return null;
}
}
What should it be I missing?

Check your web.config, msdn and code (because there could be no matching EnableSsl in the configuration file.
You may also need to enable access for "less secure apps" in your gmail settings page. here
This is necessary if you are getting the exception "`The server response was: 5.5.1 Authentication Required. Then below code should works.
var client = new SmtpClient("smtp.gmail.com", 587)
{
Credentials = new NetworkCredential("username", "password"),
EnableSsl = true
};
client.Send("username#gmail.com", "username#gmail.com", "subject", "body");

Related

connection.getConnetion() returns 404 code on WebSphere7

I have implemented a REST service using Spring Integration.
When I try to access the service manually using main function, It is working fine.
I also tested the service using REST Client in Google Chrome and that worked. But the service is coming back with responseCode 404 on WebSphere server. So I am facing the issue when I deploy the code on higher environment.
URL u = new URL("http://localhost:8080/MyApplication/testRestService");
URLConnection uc = u.openConnection();
HttpURLConnection connection = (HttpURLConnection) uc;
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept","*/*");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
OutputStream out = connection.getOutputStream();
Writer wout = new OutputStreamWriter(out);
//helper function that gets a string from a dom Document
String input = jsonInput;
wout.write(input.getBytes());
wout.flush();
wout.close();
// Response
int responseCode = connection.getResponseCode();
Is is dependent on server, so its coming back with response code 404 ? Do we need any server side configuration ?
Any suggestion will be appreciated.
Why do you use different ContentType for URLConnection and for httpClient?
Show, please, your REST service config: 404 means Not found. Therefore you use (or don't) some options in request which makes it non-matching for the server's RequestMapping.
I tried with Apache HTTP Client and the code is working on WebSphere now. Still I am not able to find the reason why java.net.HttpURLConnection was not working on WebSphere.
Please find my updated code below :
DefaultHttpClient httpClient = null;
HttpPost postRequest = null;
StringEntity inputEntity = null;
HttpResponse response = null;
try{
//RETREIVE WEB SERVICE URL FROM DB
String callbackURL = "http://localhost:8080/MyApplication/testRestService";
httpClient = new DefaultHttpClient();
postRequest = new HttpPost(callbackURL);
String inputData = request.toString();
inputEntity = new StringEntity(inputData);
inputEntity.setContentType("application/x-www-form-urlencoded");
postRequest.setEntity(inputEntity);
response = httpClient.execute(postRequest);
if (response.getStatusLine().getStatusCode() != 201 && response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "+ response.getStatusLine().getStatusCode());
}
//System.out.println("HTTP Response Code :"+response.getStatusLine().getStatusCode());
LOGGER.debug("HTTP Response Code :"+response.getStatusLine().getStatusCode());
httpClient.getConnectionManager().shutdown();
}catch(IOException ex){
ex.printStackTrace();
throw ex;
}finally{
httpClient.getConnectionManager().shutdown();
httpClient = null;
postRequest = null;
inputEntity = null;
response = null;
}

Kerberos Authentication header for JAX-WS client

I am generating my web service using ws-import to connect to an aspx service that I have secured with Kerberos on IIS.
I am able to connect and authenticate fine when I just connect to the service using a SOAPConnection
final SOAPConnection conn = SOAPConnectionFactory.newInstance().createConnection();
try {
final MessageFactory msgFactory = MessageFactory.newInstance();
final SOAPMessage message = msgFactory.createMessage();
final MimeHeaders headers = message.getMimeHeaders();
if (spnegoToken != null) {
headers.addHeader("SOAPAction", "http://tempuri.org/HelloWorld");
headers.addHeader("Authorization", "Negotiate " + Base64.encode(spnegoToken));
}
message.getSOAPBody().addBodyElement(new QName("http://tempuri.org/", "HelloWorld", "tem"));
final SOAPMessage response = conn.call(
message, "http://server:9994/WebService/SampleService.asmx");
return response.getSOAPBody().getTextContent();
} finally {
conn.close();
}
However I am unable to add an Authorization header to the JAXWS generated WS in the same way:
final SampleServiceSoap sss= new SampleService().getSampleServiceSoap();
((BindingProvider) sss).getRequestContext().put(
"Authorization", "Negotiate " + Base64.encode(spnegoToken));
return sss.helloWorld();
I get a 401 error as the token as I cannot see the token attached in Wireshark.
Can anyone point me at the approach I should take?
Cheers,
Barry
Sorted, turns out I was pretty close:
final Map<String, List<String>> headers = new HashMap<String, List<String>>();
headers.put("Authorization", Collections.singletonList("Negotiate " + Base64.encode(tgt)));
((BindingProvider) sss).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, headers);

Adding custom message header to a WCF service which is consumed from Windows Mobile 6 client

I have a WCF Service Application which server to different type of clients. While calling the service methods I want to send some spesific information within the service header.
While using a newer version of .NET Framework I can handle the situation using MessageHeader. Since the consumer can see the service as WCF Service there is no problem.
[DataContract]
public class AuthToken
{
[DataMember]
public string Username { get; set; }
[DataMember]
public string Password { get; set; }
}
Client-side:
AuthWCFSvc.Service1Client client = new AuthWCFSvc.Service1Client();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
SvcAuthClient.AuthWCFSvc.AuthToken token = new AuthWCFSvc.AuthToken();
token.Username = "wcfuser";
token.Password = "wcfpass";
MessageHeader<SvcAuthClient.AuthWCFSvc.AuthToken> header = new MessageHeader<SvcAuthClient.AuthWCFSvc.AuthToken>(token);
var untyped = header.GetUntypedHeader("Identity", "http://www.my-website.com");
OperationContext.Current.OutgoingMessageHeaders.Add(untyped);
client.TestHeader();
}
Server-side :
MessageHeaders headers = OperationContext.Current.IncomingMessageHeaders;
AuthToken token = headers.GetHeader<AuthToken>("Identity", "http://www.my-website.com");
But there are Windows Mobile 6 devices with .NET Framework 3.5 Compact Edition, using these services as well. Due to technological restrictions, they only can process the WCF services as Web Services.
If a client is consuming a WCF service as Web Service how can add spesific header information and resolve the header information at the service method?
As you know, on .NET CF 3.5 you can only use WCF as standard webservice on SOAP way. Therefore, you can't use any of WCF native security resources.
I figured out how to use Basic Http Authentication, configuring client and server sides and I can explain it as follows:
Client Side
On client side (on your device with .Net CF 3.5), its easy. Just inform your credentials configuring your clientServiceProxy by using:
var service = new YourServiceNamespace.YourService();
service.Credentials = new NetworkCredential("login", "12345");
service.PreAuthenticate = true;
This will make your client deal with the "WWW-Authenticate" header from the server response and pass your credentials automatically via the response header "Authorization: Basic".
Server Side
On the WCF configuration on your web.config, you should configure security just for Transport, and use HTTPS (this is enough to protect your message from sniffers).
<basicHttpBinding>
<binding>
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
Now, as WCF doesn't has native support for Basic Http Authentication, we have to use a custom HTTP module to deal with it.
public class BasicHttpAuthentication : IHttpModule
{
public delegate bool AuthenticateDelegate( string username, string password );
public static AuthenticateDelegate AuthenticateMethod;
public void Dispose() { }
public void Init( HttpApplication application )
{
application.AuthenticateRequest += this.OnAuthenticateRequest;
application.EndRequest += this.OnEndRequest;
}
private void DenyAccess( HttpApplication app )
{
app.Response.StatusCode = 401;
app.Response.StatusDescription = "Access Denied";
// Write to response stream as well, to give user visual
// indication of error during development
app.Response.Write( "401 Access Denied" );
app.CompleteRequest();
}
private void OnAuthenticateRequest( object source, EventArgs eventArgs )
{
if ( AuthenticateMethod == null )
return;
var app = ( HttpApplication )source;
//the Authorization header is checked if present
string authHeader = app.Request.Headers["Authorization"];
if ( !string.IsNullOrEmpty( authHeader ) )
{
string authStr = app.Request.Headers["Authorization"];
if ( string.IsNullOrEmpty( authStr ) )
return; // No credentials; anonymous request
authStr = authStr.Trim();
if ( authStr.IndexOf( "Basic", 0 ) != 0 )
// header is not correct...we'll pass it along and
// assume someone else will handle it
return;
authStr = authStr.Trim();
string encodedCredentials = authStr.Substring( 6 );
byte[] decodedBytes = Convert.FromBase64String( encodedCredentials );
string s = new ASCIIEncoding().GetString( decodedBytes );
string[] userPass = s.Split( new[] { ':' } );
string username = userPass[0];
string password = userPass[1];
if ( !AuthenticateMethod( username, password ) )
this.DenyAccess( app );
}
else
{
app.Response.StatusCode = 401;
app.Response.End();
}
}
private void OnEndRequest( object source, EventArgs eventArgs )
{
//the authorization header is not present
//the status of response is set to 401 and it ended
//the end request will check if it is 401 and add
//the authentication header so the client knows
//it needs to send credentials to authenticate
if ( HttpContext.Current.Response.StatusCode == 401 )
{
HttpContext context = HttpContext.Current;
context.Response.StatusCode = 401;
context.Response.AddHeader( "WWW-Authenticate", "Basic Realm=\"Please inform your credentials\"" );
}
}
}
To enable the HTTP module, add the following to your web.config file in the system.webServer section:
<system.webServer>
<modules>
<add name="BasicHttpAuthentication"
type="BasicHttpAuthentication, YourAssemblyName"/>
</modules>
Now you have to inform to the module a Function to use for validating the credentials from the client. You can see that there's a static delegate inside the module called "AuthenticateMethod", so you can inform a function on your Application_Start of your global.asax:
BasicHttpAuthentication.AuthenticateMethod = ( username, password ) => username == "login" && password == "12345";

why NotFound error occur in REST services with windows Phone app?

i tried to connect REST web servie from windows phone 8 application.
it was working proberly for weeks but after no change in it I get this generic error :
System.Net.WebException: The remote server returned an error:
NotFound.
i tried to test it by online REST Clients and services works properly
i tried to handle Exception and parse it as webException by this code :
var we = ex.InnerException as WebException;
if (we != null)
{
var resp = we.Response as HttpWebResponse;
response.StatusCode = resp.StatusCode;
and i get no more information and final response code is : "NotFound"
any one have any idea about what may cause this error?
there is already a trusted Certificate implemented on the server . the one who has the server suggested to have a DNS entry for the server, this entry should be at the customer DNS or in the phone hosts file .that what i done and worked for awhile but now it doesn't work however i checked that there is no thing changed
this is sample for Get Request it works proberly on Windwos Store apps :
async Task<object> GetHttps(string uri, string parRequest, Type returnType, params string[] parameters)
{
try
{
string strRequest = ConstructRequest(parRequest, parameters);
string encodedRequest = HttpUtility.UrlEncode(strRequest);
string requestURL = BackEndURL + uri + encodedRequest;
HttpWebRequest request = HttpWebRequest.Create(new Uri(requestURL, UriKind.Absolute)) as HttpWebRequest;
request.Headers["applicationName"] = AppName;
request.Headers["applicationPassword"] = AppPassword;
if (AppVersion > 1)
request.Headers["applicationVersion"] = AppVersion.ToString();
request.Method = "GET";
request.CookieContainer = cookieContainer;
var factory = new TaskFactory();
var getResponseTask = factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null);
HttpWebResponse response = await getResponseTask as HttpWebResponse;
// string s = response.GetResponseStream().ToString();
if (response.StatusCode == HttpStatusCode.OK)
{
XmlSerializer serializer = new XmlSerializer(returnType);
object obj = serializer.Deserialize(response.GetResponseStream());
return obj;
}
else
{
var Instance = Activator.CreateInstance(returnType);
(Instance as ResponseBase).NetworkError = true;
(Instance as ResponseBase).StatusCode = response.StatusCode;
return Instance;
}
}
catch (Exception ex)
{
return HandleException(ex, returnType);
}
}
i tried to monitor connections from Emulator and i found this error in connection :
**
Authentication failed because the remote party has closed the
transport stream.
**
You saw the client implement a server side certificate in the service. Did you have that certificate installed on the phone? That can be the cause of the NotFound error. Please, can you try to navigate to the service in the phone or emulator internet explorer prior to testing the app? If you do that, you can see the service working in the emulator/phone internet explorer? Maybe at that point internet explorer ask you about installing the certificate and then you can open your app, and it works.
Also remember if you are testing this in the emulator, every time you close it, the state is lost so you need to repeat the operation of installing the certificate again.
Hope this helps.
If you plan to use SSL in production in general public application (not company-distribution app), you need to ensure your certificate has one of the following root authorities:
SSL root certificates for Windows Phone OS 7.1.
When we had same issue, we purchased SSL certificate from one of those providers and after installing it on server we were able to make HTTPS requests to our services with no problem.
If you have company-distribution app, you can use any certificate from company's Root CA.

JBoss EAP 5.1 Server not using Windows Network Setting

I'm trying to call a web service from my application. My system is protected with a Firewall and I'm using a Proxy to access any external URL/internet access. The application is running on JBoss EAP 5.1 server. The application fails to write to the service URL with IO Exception: 'Could not transmit message'.
However, when I'm trying to access the service URL with IE/Firefox, it's opening. Although the XML response I'm receiving from Browser states a generic error - 'invalid request parameters...', which is quite obvious. Because I'm not sending a proper request XML from Browser.
I'm really confused with this disparity. I used to believe that JBoss will pick up standard windows network settings, but in my case it is not.
My code is as follows:
String strUrl = "http://theurlgoeshere";
String requestXml = "<request></request>";
String wsResponse="";
SOAPConnection conn = null;
try {
MessageFactory msgFac = MessageFactory.newInstance();
MimeHeaders mh = new MimeHeaders();
mh.setHeader("Content-Type", "text/xml; charset=UTF-8");
log.info("Request Xml:" + requestXml );
InputStream is = new ByteArrayInputStream(requestXml.getBytes("UTF-8"));
SOAPMessage reqMsg = msgFac.createMessage(mh, is);
SOAPConnectionFactory conFac = SOAPConnectionFactory.newInstance();
conn = conFac.createConnection();
SOAPMessage repMsg = conn.call(reqMsg, strUrl);
ByteArrayOutputStream out = new ByteArrayOutputStream();
repMsg.writeTo(out);
wsResponse = new String(out.toByteArray());
}
catch (Exception e) {
e.printStackTrace();
}
Got it sorted few days back. Basically I am using HttpURLConnection now to add proxy setting in the java code itself while making the Webservice call. Just closing this question, since my query is solved.
Will update the new code, if anyone needs.